手写Promise类(all/race)
手写Promise
https://zhuanlan.zhihu.com/p/144058361 完整版(含链式调用)
class promise{
constructor(fn){
//初始pending状态
this.status = 'pending';
//成功fulfilled状态,保存value值
this.value = undefined;
//拒绝rejected状态,保存reason值
this.reason = undefined;
//支持异步,使用数组而不是单一变量防止多次then调用覆盖之前的回调函数
this.onFulfilled = [];//成功的回调
this.onRejected = []; //失败的回调
let resolve = value => {
if(this.status == 'pending'){
this.status = 'fulfilled';
this.value = value;
//成功异步执行在此调用
this.onFulfilled.forEach(fn=>fn(value));
}
};
let reject = reason => {
if(this.status == 'pending'){
this.status = 'rejected';
this.reason = reason;
//失败异步执行在此调用
this.onRejected.forEach(fn => fn(reason));
}
}
try{
fn(resolve,reject);
}catch(e){
reject(e);
}
}
//onFulfilled,onRejected都是可选参数,如果不是函数则需要忽略
then(onFulfilled,onRejected){
if (this.status == 'fulfilled'){
typeof onFulfilled === 'function' && onFulfilled(this.value);
}
if (this.status == 'rejected') {
typeof onRejected === 'function' && onRejected(this.reason);
}
// 异步状态来不及改变,如果还是pending则将回调先存储而不是立即调用
if (this.status === 'pending') {
typeof onFulfilled === 'function' && this.onFulfilled.push(onFulfilled);
typeof onRejected === 'function' && this.onRejected.push(onRejected);
}
}
catch(onRejected){
if (this.status == 'rejected') {
typeof onRejected === 'function' && onRejected(this.reason);
}
if (this.status === 'pending') {
typeof onRejected === 'function' && this.onRejected.push(onRejected);
}
}
//手写简易promise.all
//要想使用类.方法调用需要定义为静态方法
static all(promises){
//没写如果没传入promise,只是做了抛出异常,实际上要转换为promise对象
if (!Array.isArray(promises)) {
throw new Error('promises must be an Array')
}
return new promise(function (res, rej) {
let length = promises.length;
let result = [];
for (let i = 0; i < length; i++) {
//由于定义的这个类resolve方法没有返回值用的是原生Promise
Promise.resolve(promises[i]).then(function (value) {
result[i] = value;
if (i == length-1) {
return res(result);
}
}, function (reason) {
return rej(reason);
})
}
})
}
//手写简易promise.race
static race(promises){
if (!Array.isArray(promises)) {
throw new Error('promises must be an Array')
}
return new promise(function(res,rej){
promises.forEach(p=>{
p.then(function(value){
return res(value);
},function(reason){
return rej(reason);
})
})
})
}
}前端问题总结 文章被收录于专栏
总结一些前端常见的面试笔试题,来和大家分享鸭
迅雷公司福利 193人发布