测试 ES6 Promise 对象的链式传值
Promise.resolve(1).then(
x=>{
console.log('then1 get '+x)
return 2;
}
)
.catch()
.then().then()
.then(x=>console.log('then4 get '+x))
第 1 个 then 的回调函数有返回值,后跟一个啥也不干的 catch (),再跟两个啥也不干的 then (),最后再跟第 4 个 then ()
第 4 个 then 有输出,可见第 1 个 then 的返回值跳过了中间的 catch 及其后的两个空 then,直接传给了第 4 个 then
> "then1 get 1"
> "then4 get 2"
如果删除第 4 行的 return 2
,导致第一个 then 没有返回值,得到的结果会是下面这样
> "then1 get 1"
> "then4 get undefined"
断链#
截图使用 .reject () 产生一个错误。从截图的中间一例可以看出,空的 .catch () 函数实际上不会捕获异常,等于不存在。如果有异常,却不能被捕获,那 promise 链便会就此断开,后续的 then () 统统不执行。
续链#
截图最后一例是一个续链的例子。错误抛出后被捕获,promise 链继续向后传播,因此可以看到 then4 get undefined 了。如果捕获异常,并且有返回值,那么 then4 就会打印这个返回值。
Promise.reject(1).then(
x=>{
console.log('then1 get '+x)
return 2;
}
)
.catch(err=>{console.log('捕获', err);return '救星'})
.then().then()
.then(x=>console.log('then4 get '+x))
//结果如下
// 捕获 1
// then4 get 救星
拒绝续链#
以下截图对比了续链与拒绝续链的区别。两段代码的区别仅仅在于 catch () 函数的返回值是不同的。
续链:return '救星'
断链:return Promise.reject(err)
续链后 then4 继续执行;拒绝续链后 then4 没机会执行。
拒绝续链的应用场景#
以 promise-gif 为例,此插件的用法一行代码概括如下:Promise.resolve().gif().then(...).catch(...)
以上 Promise 链里面实际上有两个 catch,其中 gif () 函数内部也有一个 catch。
通过 gif () 打开无限风火轮动画,当业务代码执行成功后,关闭风火轮是显而易见的。当业务代码执行失败后,风火轮也必须关闭,因此 promise-gif 必须捕获异常。但是业务代码可能会有自己的异常捕获逻辑,因此 promise-gif 在捕获异常后必须做两件事:1、关闭风火轮;2、拒绝续链并继续报错。
这便是拒绝续链的应用场景。由此可见,在一条 promise 链里面添加多个 catch () 函数的做法很有意义。每个 catch () 函数只处理特定的逻辑,完毕后继续报错,这样就可以使得整条 promise 链里面的其他 catch () 函数仍有执行的机会。
promise 链的 promise 返回与不返回的区别#
第 2 个 then 函数里面新建一个 promise,一秒之后将其 resolve 掉。加不加 return 决定了后续 then 的回调函数是否异步执行
加了 return 则 then4 延迟执行
不加 return 则 then4 提前执行,它不会等到 then2 执行之后才执行
Promise.reject(1).then(
x => {
console.log('then1 参数为 ' + x)
return 2;
}
)
.catch(err => {
console.log('捕获', err);
return '继续'
})
.then(
x => {
return new Promise(function (resolve, reject) {
setTimeout(
(y) => {
console.log('then2 参数为 %s, setTimeout() 参数为 %O', x, y)
resolve('久等了')
}, 1000, [2, 4, 6, 8]
)
})
}
)
.then()
.then(x => console.log('then4 参数为 ' + x))
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: