相信很多人面试的时候都被问过:
你能手写一个Promise么?
肯定可以呀,手写没问题,不要求脚写就ok。
不多逼逼,show you the code。
function Promise(executor) {
this._status = "Pending";
this._subPromiseResolves = [];
this._subPromiseRejects = [];
this._value = undefined;
let resolve = (val) => {
if(this._status !=== "Pending") return
this._status = "Resolved";
this._value = val;
this._subPromiseResolves.forEach((resolve) => {
resolve(val);
})
}
let reject = (reason) => {
if(this._status !=== "Pending") return
this._status = "Rejected";
this._value = reason;
this._subPromiseRejects.forEach((reject) => {
reject(reason);
})
}
executor(resolve, reject);
}
Promise.resolve = (val) => {
return new Promise((resolve) => {
resolve(val);
})
}
Promise.reject = (val) => {
return new Promise((resolve, reject) => {
reject(val);
})
}
Promise.prototype.then = function(onResolved, onRejected) {
let newPromise;
switch(this._status) {
case "Resolved":
if(onResolved) {
newPromise = Promise.resolve(onResolved(this._value));
}else {
//值穿透
newPromise = Promise.resolve(this._value);
}
break;
case "Rejected":
if(onRejected) {
newPromise = Promise.resolve(onRejected(this._value));
}else {
//错误往下冒泡
newPromise = Promise.reject(this._value);
}
break;
case "Pending":
newPromise = new Promise((resolve, reject) => {
//给前一个Promise存一个能触发回调并改变状态的函数
this._subPromiseResolves.push(function(val){
resolve(onResolved(val));
});
this._subPromiseRejects.push(function(val){
reject(onRejected(val));
});
})
}
return newPromise
}
Promise.prototype.catch = function(onRejected){
return this.then(null, onRejected);
}
复制代码
ps:这段代码实现了Promise的then
、catch
、链式写法...等功能,还有挺多的功能没加上,不过相信看懂这段代码的大家都有能力为它添加更多的功能。
**祝大家新年快乐**