主页
主页
文章目录
  1. 1. promise catch
  2. 2. promise all
  3. 3. promise race
  4. 4. promise.finally
  5. 5. 如何终止一个promise
  6. 6. 如果取消一个promise

promise下

1. promise catch

首先我们要明确其实catch就是.then(null, rejection)的语法糖。所以他仍然返回一个promise,可以继续.then执行

1
2
3
4
5
6
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第一个参数成功回调中的错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
});

// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});

2. promise all

简单的promise源码实现如下:
内部会有计数器,等所有执行完毕后才会置换状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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: 报错了]

3. promise race

只要有一个状态改变,就马上返回。所以他的源码比all要简单。没有计数器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

1
2
3
4
5
6
7
8
9
10
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);

4. promise.finally

promise.finally 的源码也很简单。执行下回调并且原值返回之前的参数

1
2
3
4
5
6
7
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 })
);
};

5. 如何终止一个promise

1
2
3
new Promise(resolve => {
resolve(new Promise(resolve=>{})); // return一个pendding状态的promise即可
}).then(res => {console.log(res)})

6. 如果取消一个promise

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
支持一下
扫一扫,支持superkimi
  • 微信扫一扫
  • 支付宝扫一扫