Promise概念
Promise,字面意思是一个承诺,实际是为了解决异步回调地狱问题提出的方案。在没有Promise的异步回调中很容易行程下面结果:
fetchData(url, res1 => {
fetchData(res1.url, res2 => {
fechData(res2.url, res3 => {
console.log(res3)
...
}
}
})
而Promise的出现,不仅提供了异步解决方案,还提供了链式调用方便了阅读和书写。
封装Promise
class myPromise {
promiseState = 'pedding';
promiseResult;
callbacks = [];
catchHandler;
executor;
constructor(executor) {
this.executor = executor;
this.executor(this.onResolve.bind(this), this.onReject.bind(this));
};
onResolve(res) {
this.promiseState = 'resolved';
this.promiseResult = res;
// 当状态改变为【成功】时,执行所有成功回调
this.callbacks.forEach(item => item.resovleCallBack(res));
return this.promiseResult;
};
onReject(err) {
this.promiseState = 'rejected';
this.promiseResult = err;
// 当状态改变为【失败】时,执行所有失败回调
this.callbacks.forEach(item => item.rejectCallBack(err));
if (this.catchHandler) {
this.catchHandler(err);
}
return this.promiseResult;
};
then(onResolve, onReject) {
let self = this;
// 返回新的promise对象
return new myPromise((resovle, reject) => {
switch (self.promiseState) {
case 'resolved':
resovle(onResolve(self.promiseResult));
break;
case 'rejected':
reject(onReject(self.promiseResult));
break;
// 处理异步
case 'pedding':
self.callbacks.push({
resovleCallBack: function (res) {
resovle(onResolve(res));
},
rejectCallBack: function (err) {
reject(onReject(err));
}
});
}
})
};
catche(onReject) {
// 如果当前Promise实例状态 不为【rejected】时,返回当前实例
if (this.promiseState !== 'rejected') {
return this;
}
return new myPromise((resovle, reject) => {
// 处理异常穿透
this.catchHandler = function (err) {
onReject(err);
reject(err);
}
});
}
static resolve(res) {
return new myPromise((resolve, reject) => {
resolve(res);
});
};
static reject(err) {
return new myPromise((resolve, reject) => {
reject(res);
});
};
static all(list) {
const result = [];
let count = 0;
function collectResult(res, resolve) {
result.push(res);
count++;
if (count === list.length) {
resolve(result);
}
};
return new myPromise((resolve, reject) => {
list.forEach(item => {
if (item instanceof myPromise) {
item.then(res => {
collectResult(res, resolve);
}, err => {
reject(err);
});
} else {
myPromise.resolve(item).then(res => {
collectResult(res, resolve);
});
}
});
});
};
static race(list) {
return myPromise((resolve, reject) => {
list.forEach(item => {
if (item instanceof myPromise) {
item.then(res => {
resolve(res);
}, err => {
reject(err);
});
} else {
resolve(myPromise.resolve(item));
}
})
});
}
}