本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
大家好,我是除了开发,什么都想试试的布布。目前Promise 是 JavaScript 异步编程的一种流行解决方案,那理解promise原理早该提上日程了。理解原理?除了原生手写promise库,还能有什么更好的解决办法吗?
实现promise周边方法
上一期已经实现了状态以及then的相关问题,手写promise其实也已经接近尾声了,这一期主要实现周边方法。(本期代码是在上一期代码的基础上,进行的补充,所以请至上期文章最后copy全代码)
周边方法主要分为两大类:
- 原型方法 catch 、finally
- 静态方法 race all allSettled resolve reject
catch
注册 catch 方法来处理错误,在then之后调用,与try/catch语句有相同的功能。then会返回一个promise对象,所以catch也是promise对象中的一个方法。catch中传入的是一个函数。
catch(fn) {
return this.then(undefined, fn);
}
resolve reject
都返回一个新的promise对象。
static resolve(val) {
return new MPromise(resolve => {
resolve(val);
})
}
static reject(err) {
return new MPromise((resolve, reject) => {
reject(err);
})
}
finally
注意执行顺序,无论成功还是失败都要执行,需要注册到执行队列里面。
finally(cb){
this.then(cb,cb);
}
race
接收数组,执行之后调用then 方法,则说明race返回的是一个promise对象,成功或失败都是抛出数组中执行最快的那个结果(注意:如果已经抛出成功或失败需要控制就不再抛出)。
static race(lists) {
let isExe = false;
return new KPromise((resolve, reject) => {
lists.forEach(item => {
item.then(res => {
if (!isExe) {
resolve(res);
isExe = true;
}
}, err => {
if (!isExe) {
reject(err);
isExe = true;
}
})
})
})
}
all
将所有结果收集起来进行返回,但注意只返回成功的结果集,失败的收集不到
static all(lists){
let resArr = [];
let num = 0;
return new MPromise(resolve=>{
lists.forEach(item=>{
item.then(res=>{
num++;
resArr.push(res);
if(resArr.length===lists.length){
resolve(resArr);
}
})
})
})
}
allSettled
把成功和失败的返回结果收集起来之后,返回到成功的resolve里,找合适的位置进行抛出。
static allSettled(lists){
let resArr = new Array(lists.length);
let num = 0
return new KPromise(resolve=>{
lists.forEach((item,key)=>{
let obj = {};
item.then(res=>{
obj['status'] = "fulfilled";
obj['value'] = res;
resArr[key] = obj;
num++;
if(num>=lists.length){
resolve(resArr);
}
},err=>{
obj['status'] = "rejected";
obj['reason'] = err;
resArr[key] = obj;
num++;
if(num>=lists.length){
resolve(resArr);
}
})
})
})
}
好了,promise周边方法已经写得差不多了,下面写点面试题练练吧!
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(1);
}, 1000)
})
// 1
promise.then(() => {
return Promise.resolve(2);
}).then((n) => {
console.log(n)
});
// 2
promise.then(() => {
return 2
}).then((n) => {
console.log(n)
});
// 3
promise.then(2).then((n) => {
console.log(n)
});
评论区写下你的答案吧!