Promise链
有时候我们需要异步的执行一系列任务,Promise提供了很好的方式来实现这一操作。
Promise链实现原理
1.then()的返回值:如果返回的是一个普通值如基本数据类型,则会包装为promise对象以保证链式调用,当然也可以手动new一个promise对象返回。
其中then(handler) 中所使用的处理程序在这种情况下,其他的处理程
序将等待它 settled 后再获得其结果。
2.考虑在执行then前promise对象的状态
pending 状态:如果 promise对象 在 pending 状态下执行了 then ,我们就等待 excutor 中的 resolve 或者 reject 被执行
resolve 执行:如果 status === ‘pending’ 接受一个value参数并返回一个promise对象并将此对象状态从pending改为fulfilled。此刻then开始可以调用
reject 执行:如果 status === ‘pending’,改状态为 ‘rejected’。此刻then开始可以调用
简单示例
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
}).then(function(result) {
alert(result);
return result * 2;
}).then(function(result) {
alert(result);
return result * 2;
}).then(function(result) {
alert(result);
return result * 2;
});
输出结果:1 2 4
在构造器中设置了setTimeout来模拟异步执行。第一个then执行时需要等待promise对象的状态从pending到fulfilled或者rejected。在上例中会有1秒的等待时间。
运行流程如下:
初始 promise 在 1 秒后 resolve
然后 .then 处理程序被调用,它又创建了一个新的 promise(以 2 作为值 resolve)。
下一个 then 得到了前一个 then 的值,对该值进行处理(*2)并将其传递给下一个处理程序。
……依此类推。
Promise中的异常处理机制
promise的异常处理十分独特。构造器中的 承诺内容(executor) 以及其他处理程序(then(),catch()…)被一个隐式的try…catch包裹,如果发生异常则会将promise对象的状态设置为rejected并移交至最近的catch处理程序进行异常捕获,来返回一个新的promise对象(由于错误被捕获,这个对象的状态也会更新)。但是如果没有catch去捕获错误. error 会“卡住”。没有代码来处理它。下面2个例子将进行验证
let promise =new Promise(function(resolve, reject) {
throw new Error("我是个错误");
}).catch(err=>{
console.log(err)
})
console.log(promise)
这段代码在executor中抛出异常并设置了捕获程序,catch将异常捕获并返回一个新的promise更新掉了rejected状态。因此承诺会正常结束。
let promise =new Promise(function(resolve, reject) {
throw new Error("我是个错误,而且没有被解决!");
})
console.log(promise)
因为异常没有被捕获,可以看到程序因为没有捕获的错误而报错。promise的状态此时也是rejected
Promise链中的异常处理机制
相比promise异常的处理.链中常常存在一连串的then调用。当异常发生时promise状态改为rejected。当一个 promise 被 reject 时,控制权将移交至最近的 异常 处理程序。下面代码将进行进一步解释:
1.可以看到22行代码 返回了一个具有rejected状态的promise对象。则会立即移交到最近的异常处理程序.由于下面的then(res=>{})没有异常处理程序,则不会执行且继续向下寻异常处理程序。
2.在32行中,在catch中再次抛出异常。那么控制权就会被移交到下一个最近的 error 处理程序。如果我们处理该 error 并正常完成,那么它将继续到最近的成功的 .then 处理程序。