手写promise的方法(all、race、allSettled、any、finally),你会几个
Promise里面大有文章,不过基础的几个方法你知道怎么写的吗?一起来看看!
·
手写promise相关方法
最近一段时间很懒,一直没有写博客,今天试着手写了一些promise相关的方法,一起看看吧!
1、Promise.all
特点:
- Promise.all() 方法接收一个promise的iterable类型(MDN)
- 只返回一个promise实例
- 当传入的参数promise全部成功时,最后的结果才会成功(成功的结果是所有的promise的成功的结果组成的数组),只要有一个promise失败,all返回的实例就是一个失败的promise(失败的结果是传入的参数中的第一个失败的promise的结果)
具体实现:
let p1 = new Promise(resolve => {
setTimeout(resolve, 200, 1)
});
let p2 = new Promise((resolve, reject) => reject(2));
let p3 = 3;
console.log(Promise.all([p1, p2, p3]));//all方法
let myAll = function(parr) {
let result = [],//最后成功的结果
count = 0,//累加器,与len比较判断是否全部成功了
len = parr.length;
return new Promise((resolve, reject) => {
for (let p of parr) {//依次测试传入的参数(转化为promise)是否是成功的
Promise.resolve(p).then(res => {
result[count] = res;//成功就加入到结果中
count++;//累加器加一
if (count == len) {//如果相等,说明都成功了,可以走成功resolve
resolve(res);
}
}, err => {
//只要有一个失败了,直接走失败reject
reject(err);
})
}
})
}
console.log(myAll([p1, p2, p3]));
2、Promise.race(比比谁先改变状态!)
特点:
- 传入的参数和返回的结果形式和all方法一样
- 区别:只要传入的promise有一个状态改变了,最后的结果就会立即改变
- 例如有一个成功,直接走race的resolve,如果有一个失败,直接走reject
具体实现:
let p1 = new Promise(resolve => {
// setTimeout(resolve, 0, 1)//大家猜猜如果是这句,最后是什么结果
resolve(1);
});
let p2 = new Promise((resolve, reject) => reject(2));
let p3 = 3;
let myRace = function(parr) {
return new Promise((resolve, reject) => {
for (let p of parr) {//一次检查
Promise.resolve(p).then(resolve, reject);//只要是状态改变了就直接走对应的函数
//也可以是这样
//Promise.resolve(p).then(res => {
// resolve(res);
//},err=>{
// reject(err);
//});
}
})
}
console.log(myRace([p1, p2, p3]));
这里使用了简写,看不懂的小伙伴可以看看我这篇promise的then方法
3、Promise.any
特点:
- 几乎和all方法“一样”
- 区别:all是所有都成功最后才成功,一个失败了,最后就失败,allSettled是只要有一个成功了最后就是成功了,遇到失败的还是继续监测,直到找到成功的或者检查完。
- 好理解一点就是,all方法类似于Array的every方法,any类似于Array的some方法
具体实现:
let p1 = new Promise(resolve => {
setTimeout(resolve, 200, 1)
});
let p2 = new Promise((resolve, reject) => reject(2));
let p3 = 3;
console.log(Promise.any([p1, p2, p3]));
let myAny = function(parr) {
let res = [],
count = 0,
len = parr.length;
return new Promise((resolve, reject) => {
for (let p of parr) {
Promise.resolve(p).then(res => {
resolve(res);//只要有一个成功,就走resolve
}, err => {
res[count] = err;//遇到错误先不管,继续检查
if (++count == len) {//直到遇到成功的或检查完
reject(res);
}
})
}
})
}
console.log(myAny([p1, p2, p3]));
4、Promise.allSettled
特点:
-
传参和返回值和all方法一样
-
返回值都是已成功状态(不论传入的是已成功还是已失败的promise)
-
一旦所指定的 promises 集合中每一个 promise 已经完成,无论是成功的达成或被拒绝,未决议的 Promise将被异步完成。那时,所返回的 promise 的处理器将传入一个数组作为输入,该数组包含原始 promises 集中每个 promise 的结果。
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。——MDN
具体实现:
let p1 = new Promise(resolve => {
setTimeout(resolve, 200, 1)
});
let p2 = new Promise((resolve, reject) => reject(2));
let p3 = 3;
console.log(Promise.allSettled([p1, p2, p3]));
Promise.myAllSettled = function(parr) {
let len = parr.length;
let result = new Array(len);
let count = 0;
return new Promise((resolve, reject) => {
for (let p of parr) {
Promise.resolve(p).then(res => {//成功:加入装状态列表
result[count] = {//记录当前promise信息
status: "fullfilled",
result: res
};
if (++count == len) {//遍历完,走resolve
resolve(result);
}
}, err => {//失败:加入状态列表
result[count] = {//记录当前promise状态信息
status: "rejected",
result: err
}
if (++count == len) {//遍历完依然走resolve
reject(result);
}
})
}
})
}
console.log(Promise.myAllSettled([p1, p2, p3]));
我对于这个方法的理解:对于一些互不依赖的请求,不论他们是否完成期约,你都想看看他们最终的状态的时候,就可以使用这个方法。
这个最后实现和本体还是有区别的,具体大家看这个最后的结果就知道了(暂时我未解决,如有知道的欢迎评论私信)
5、Promise.prototype.finally
特点:
- 在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
- 避免了同样的语句需要在then()和catch()中各写一次的情况。
MDN
具体实现:
Promise.prototype.myFinally = function(cb) {//cb就是要共同执行的逻辑
return this.then(//谁调用finally,this就是谁
value => Promise.resolve(cb()),//不管调用finally的promise是什么状态都会执行这个cb
error =>//不管调用finally的promise是什么状态都会执行这个cb
Promise.resolve(cb())
);
};
let p2 = new Promise((resolve, reject) => resolve(2));
p2.finally(() => {
console.log("finally");
})
p2.myFinally(() => {
console.log("myFinally");
})
上面这个**Promise.resolve(cb())**看不懂的小伙伴,记得看这里👇
promise的then方法
好啦,今天的分享就到这里了,看到这里了就点个赞再走呗😁
更多推荐
所有评论(0)