前一篇文章梳理了promise的基础聊聊promise系列(基础)promise
这篇文章将从容易出现错误的几种用法出发,得出如何去正确的用promise。bash
想必你们在项目中会见过这样的写法。函数
const p1 = new promise((resolve, reject) => {
resolve(true);
})
p1.then((res) => {
if(res) {
const p2 = new promise((resolve, reject) => {
resolve(true);
})
p2.then((res) => {
const p3 = new promise((resolve, reject) => {
resolve(true);
})
})
}
})
复制代码
这个写法写出了回调地狱的感受。那如何优化他呢!!post
const p1 = new promise((resolve, reject) => {
resolve(true);
})
const p2 = new promise((resolve, reject) => {
resolve(true);
})
const p3 = new promise((resolve, reject) => {
resolve(true);
})
p1.then((res) => {
if(res) {
return p2
}
}).then((res) => {
if(res) {
return p3
}
})
复制代码
用这种链式调用的方式仍是十分的优雅的。优化
举个等价的例子:ui
Promise.reject('error').catch((res) => {
console.log(res);
})
Promise.reject('error').then(null, (res) => {
console.log(res);
})
复制代码
catch
是用then(null, ...)
来实现的,可是在某些条件下,并非等价的,好比如下例子:spa
const p1 = new Promise((resolve, reject) => {
if(/*正确的条件*/) {
resolve('success');
} else {
reject('false');
}
});
//用法一:
p1.then((res) => {
console.log(res);
throw new Error('我在then出错了');
}, (res) => {
console.log(res);
});
//用法二:
p1.then((res) => {
console.log(res);
throw new Error('我在then出错了');
}).catch((res) => {
console.log(res);
})
复制代码
上述例子的区别就在与,catch能够捕捉then中发生的错误,可是then的第二个回调函数捕捉不了第一个参数中的报错。
复制代码
输出的结果:3d
什么是promise穿透问题呢?举个例子:code
Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
console.log(result);
});
复制代码
这个鬼东西会输出啥??cdn
斟酌良久,你可能回答bar,那你就错了,实际输出的是foo。
由于then
中但愿得到的是一个函数。而当你传入一个promise
的时候,至关于then(null)
,不管你添加多少个then(null)
,promise都会穿透到下一个。
固然,对于上述例子,你可能但愿的是这样作:
Promise.resolve('foo').then(() => {
return Promise.resolve('bar');
}).then(function (result) {
console.log(result);
});
复制代码
切记,必定要往then里面传入函数
接下来,咱们经过一个例子,来看一下不一样写法带来的后果。
const func = function(last, num) {
return new Promise((resolve, reject)=>{
console.log(last, num);
resolve(num);
});
};
// 写法一
Promise.resolve()
.then((last)=>{return func(last, 1);})
.then((last)=>{return func(last, 2);})
.then((last)=>{return func(last, 3);});
// 写法二
Promise.resolve()
.then((last)=>{func(last, 1);})
.then((last)=>{func(last, 2);})
.then((last)=>{func(last, 3);});
// 写法三
Promise.resolve()
.then(func(undefined, 1))
.then(func(undefined, 2))
.then(func(undefined, 3));
// 写法四
func(undefined, 1).then(func(undefined, 2)).then(func(undefined, 3));
复制代码
结果:
undefined 1
1 2
2 3
复制代码
这是咱们想要的结果,也是promise链式调用正确的写法。
undefined 1
undefined 2
undefined 3
复制代码
虽然在then中执行了函数,可是并无return有结果的promise给下一个then,因此后面的then永远是收不到结果值的。
结果:
undefined 1
undefined 2
undefined 3
复制代码
这种写法是形成promise穿透引发的。then里面须要是一个函数,可是却传了一个promise进去。
结果:
undefined 1
undefined 2
undefined 3
复制代码
和第三种也发一致,也是promise穿透,then里面须要是一个函数,可是却传了一个promise进去。