1. 概念
Promise对象用于异步(asynchronouss)计算,一个Promise对象代表着一个还未完成,但预期完成的操作。
2. 出现原因:
1) 如果你需要通过ajax发送多次请求,而每一次请求依赖上一次请求返回的结果作为参数来继续下次的请求,这样的话,就需要这么写代码:
上面的例子,假设请求C需要依赖B返回的数据,那么C需要放在B的success函数里面。同样的,A需要依赖B返回的数据,那么A也需要放在B的success函数里面。假设现在存在很多个请求,请求之前是相互的依赖关系,那么我们需要嵌套很多层,这样的话,代码的可读性就很差,不直观,调试起来也不方便,维护也不方便。
2) 如果请求C需要依赖A和B的结果,而A,B是互相独立的,没有依赖关系,那么如果使用上面的实现方法,就使得A(B)需要依赖B(A)完成之后才能调用,这样需要更长的等待时间。
所以,为了处理这种回调函数层层嵌套的问题(又称“回调地狱”),所以Promise就出现了。
3. 语法
new Promise(function(resolve,reject){
//操作…
});
Promise对象是全局对象,你也可以理解为一个类,创建Promise实例的时候,利用new关键字。其中,resolve和reject两个参数是函数对象。resolve是用于处理执行成功的场景,reject是用在处理执行失败的场景,一旦操作完成就可以调用这两个函数。具体的调用是通过then()方法来绑定操作后的处理程序,具体使用见之后的讲解。
4. 解析
Promise对象的三种状态:
1) pending:刚刚创建一个Promise实例的时候,表示初始化状态
2) fulfilled:resolve方法调用的时候,表示操作成功
3) rejected:reject方法调用的时候,表示操作失败
pending状态的promise对象既可转换为带着一个成功值的fulfilled 状态,也可变为带着一个失败信息的 rejected 状态。当状态发生转换时,promise.then绑定的方法(函数句柄)就会被调用。(当绑定方法时,如果 promise对象已经处于 fulfilled 或 rejected 状态,那么相应的方法将会被立刻调用, 所以在异步操作的完成情况和它的绑定方法之间不存在竞争条件。)
(图片来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)
5. 属性
Promise.length:长度属性,其值为1(构造参数的数目)
Promise。prototype:Promise构造器的原型
6. 方法
1) Promise.then()方法:用于绑定处理操作后的处理程序。
2) Promise.catch()方法:用于处理操作异常后的页面。
3) then()和catch()综合使用的例子:
4) 层层依赖用Promise处理:
代码:
1 let pro = new Promise(function(resolve,reject){ 2 if(true){ 3 resolve('操作成功');//此时resolve函数会返回值 4 } 5 else{ 6 reject('操作失败'); 7 } 8 }); 9 10 pro.then(requestA) 11 .then(requestB) 12 .then(requestC) 13 .catch(requestError); 14 15 function requestA(res){ 16 console.log(res);//输出resolve返回的值-->操作成功 17 console.log("请求A成功"); 18 return "请求A,下一步就是B你了"; 19 } 20 21 function requestB(res){ 22 console.log("上一步是"+res); 23 console.log("请求B成功"); 24 return "请求B,下一步是C你了"; 25 } 26 27 function requestC(res){ 28 console.log("上一步是"+res); 29 console.log("请求C成功"); 30 } 31 32 function requestError(){ 33 console.log("请求失败"); 34 }