Js Promise的学习

本文深入讲解了JavaScript中Promise的工作原理及使用方法,包括其三种状态、API介绍、链式调用示例等,帮助读者更好地理解和运用Promise解决异步编程难题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.我们为什么要用Promise

    javaScript处理异步都是由callback的形式执行,由js宿主环境(浏览器,node)为一些耗时任务开辟另外的线程。这种callback机制深入人心,但是它的写法会带来一些不便,我们拿ajax举例:

    

$.ajax({
  type:'post',url:'xxx.do',
  data:{},
  success:function(data){
    $.ajax({
	type:'post',url:'xxx.do',
  	data:{},
 	success:function(data){
	  $.ajax({
		type:'post',url:'xxx.do',
  		data:{},
  		success:function(data){
	          //业务代码
	  
	              }
	  	  }
                })
          }
    })
    这里举了一个极端点的例子,这个方法套了三层ajax,乍一看还是很迷糊的。但是如果同样的事交给Promise做,就清晰很多了。
new Promise(function(resolve,reject){
	$.ajax({
  type:'post',url:'xxx.do',
  data:{},
  success:function(data){
	  resolve(data);
	  		
  })
}).then(function(data){
	 
	 $.ajax({
			  type:'post',url:'xxx.do',
			  data:{},
			  success:function(data){
				 return Promise.resolve(data);	
  			  }
  	})
 }).then(function(){
	 $.ajax({
			  type:'post',url:'xxx.do',
			  data:{},
			  success:function(data){
				 //业务代码
  			  }
  	})
	 
	 
 })

    有没有发现原来层层嵌套的ajax变成平铺排列了,就好像原来是把一块一块的砖垒起来,现在是将他们平铺开了。这样不仅看起来更清晰,也将异步操作以同步的形式展现出来。接下来我们看看Promise的语法规范。

二.语法规范

    1.概念

    Promise 对象有三种状态: Pending – Promise对象的初始状态,等到任务的完成或者被拒绝;Resolved – 任务执行完成并且成功的状态;Rejected – 任务执行完成并且失败的状态;
    Promise的状态只可能从Pending状态转到Resolved状态或者Rejected状态,而且不能逆向转换,同时Resolved状态和Rejected状态也不能相互转换;
    Promise对象必须实现then方法,then是promise规范的核心,而且then方法也必须返回一个Promise对象,同一个Promise对象可以注册多个then方法,并且回调的执行顺序跟它们的注册顺序一致。这一点很重要,我觉得这个是promise被应用的主要原因,如果没有then的链式调用,跟普通callback比,没啥优势。

    then方法接受两个回调函数,它们分别为:成功时的回调和失败时的回调;并且它们分别在:Promise由Pending状态转换到Resolved状态时被调用和在Promise由Pending状态转换到Rejected状态时被调用。默认then里面第一个函数是resolve的回调,第二个是reject的回调。

2.API
Promise.resolve()       执行成功
Promise.reject()     执行失败
Promise.prototype.then()    递延处理
Promise.prototype.catch()  异常

Promise.all() 所有的完成 Promise.all方法常被用于处理多个promise对象的状态集合

三.实例

    先举一个小例子:

 var key=false;
new Promise(function(resolve, reject){
    if(key){
        resolve(123)//调用resolve,表示执行成功
    }else{
        reject(321)//调用reject,表示执行失败
    }
}).then(function(value) {
	//执行成功的回调函数
  console.log(value); // key=true 123
}, function(reason) {
	//执行失败的回调函
  console.log(reason); //key=false 321
})

再举一个例子体现then回调的异步性

javascript] view plain copy
var p = new Promise(function(resolve, reject){  
  resolve("success");  
});  
  
p.then(function(value){  
  console.log(value);  
});  
  
console.log("first");  
//"first"  
//"success"  

事实证明then的回调也是浏览器分配的线程,与主线程异步,任务放在callbackqueue里排队。


再举一个链式调用的例子:

var p = new Promise(function(resolve, reject){  
  resolve(1);  
 
});  
p.then(function(value){     
   //执行成功,接收由resolve(1)传入的回调函数参数 1,即value为1       
  console.log(value);  
  return value*2;  //返回 2,作为 执行成功回调函数的参数
}).then(function(value){   
			           //接收到回调函数的参数 value=2 
  console.log(value);  //没有返回值,执行成功 的回调函数没有传入参数
}).then(function(value){               
  console.log(value);  
   return Promise.resolve('resolve');  
  //调用resolve方法表示执行成功,并传入 'resolve'字符串作为 执行成功回调函数的参数,这里也必须用return,不用return接下来会执行resolve的回调,没有参数,执行完resolve回调后会抛出异常 
}).then(function(value){              
  console.log(value);  
  return Promise.reject('reject');  //表示执行失败,调用执行失败的回调函数
  //并传入参数reject
},
function(value){     
  console.log(value);  
  return Promise.reject('reject');  
}).then(function(value){              
  console.log('resolve: '+ value);  
}, function(err){  
  console.log('reject: ' + err);  //执行了失败的回调,接收到参数 'reject'
}) 

执行结果如图:


四.补充

    catch()的作用

        1.他可以和then的第二个参数一样,用来制定reject的回调。

        2.当执行resolve的回调,如果代码出错抛出异常时,也不会报错卡死js,会进入到catch里面

        3.添加多个catch,精准捕获异常。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值