promise catch
首先我们要明确其实catch就是.then(null, rejection)
的语法糖。所以他仍然返回一个promise
,可以继续.then执行
p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err));
// 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));
catch写法要比then中第二个参数要好。因为他捕获不到当前then第一个参数成功回调中的错误。
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});
promise all
简单的promise源码实现如下:
内部会有计数器,等所有执行完毕后才会置换状态。
Promise.all = function(promise) {
return new Promise((resolve,reject) => {
let arr = [];
let i = 0;
let processData = (index, data) => {
arr[index] = data;
if (++i === promises.length) {
resolve(arr);
}
}
for (let i = 0; i < promises.length; i++) {
let current = promises[i];
if(isPromise(current)) {
current.then(data => {
processData(i, data);
}, reject)
} else {
processData(i, current)
}
}
})
}
注意点:如果promise all中的promise有自己的catch方法。则不会走all的catch方法。会返回一个新的promise,并且resolve。所以会进入all的then中而不会走catch
const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]
promise race
只要有一个状态改变,就马上返回。所以他的源码比all要简单。没有计数器
Promise.all = function(promise) {
return new Promise((resolve,reject) => {
for (let i = 0; i < promises.length; i++) {
let current = promises[i];
if(isPromise(current)) {
current.then(data => {
resolve(i, data);
}, reject)
} else {
resolve(i, current)
}
}
})
}
promise.race可以很多改变状态的操作,比如取消promise。或者像如下 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
promise.finally
promise.finally 的源码也很简单。执行下回调并且原值返回
之前的参数
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};
如何终止一个promise,不要这个promise的结果,不像后传递?
new Promise(resolve => {
resolve(new Promise(resolve=>{})); // return一个pendding状态的promise即可
}).then(res => {console.log(res)})
如果取消一个promise
function race(p){
let obj = {};
// 定义一个空的promise。保存它的resolve 、reject 状态
let p1 = new Promise(function(resolve, reject){
obj.resolve = resolve;
obj.reject = reject;
});
obj.promise = Promise.race([p, p1]);
return obj;
}
// 需要取消时直接调用空promise的resolve即可。
// 这样race就会走成功,并且忽略掉传入的promise。达到取消的目的
obj.resolve(cancelReason);
网友评论