前段时间面试时面试官问了我如何手写一个promise,心想只手写过promise的api,那如果直接手写promise应该从哪做起呢?
Promise结构&特性
结构: 1、Promise对象创建一个异步函数 2、异步函数中有resolve 、reject 两个函数参数 3、Promise中的fulfilled 、pending 、rejected 三种状态 4、Promise的.then 执行回调返回新的Promise 5、Promise的链式编程 特性: 1、主动抛出错误,会调用 reject() 方法回调。 2、.then 中传入非函数参数,不会报错。
实现思路
1、用class类或构造函数实现Promise对象。 2、自定义resolve 、reject 方法。 3、定义三种状态,且一旦确定后不可改变。 4. then 执行回调结果。 5. 异步执行:使用定时器执行 .then 回调。 6. 链式执行:让 .then 返回一个新的 Promise 来实现链式编程。 7. 使用 try-catch 来判断代码有无主动抛出一个错误。 8. 对 .then 中传入的参数进行非函数判断,如果不为函数则将其回调赋值为一个空对象。
实现
1、
class myPromise {
static PENDING = '待定';
static FULFILLED = '完成';
static REJECTED = '拒绝';
constructor(func) {
this.status = myPromise.PENDING;
this.result = null;
this.resolveCallbacks = [];
this.rejectCallbacks = [];
try {
func(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error)
}
}
resolve(result) {
setTimeout(() => {
if (this.status === myPromise.PENDING) {
this.status = myPromise.FULFILLED;
this.result = result;
this.resolveCallbacks.forEach(callback => {
callback(result)
})
}
});
}
reject(result) {
setTimeout(() => {
if (this.status === myPromise.PENDING) {
this.status = myPromise.REJECTED;
this.result = result;
this.rejectCallbacks.forEach(callback => {
callback(result)
})
}
});
}
then(onFULFILLED, onREJECTED) {
return new myPromise((resolve,reject)=>{
onFULFILLED = typeof onFULFILLED === 'function' ? onFULFILLED : () => {};
onREJECTED = typeof onREJECTED === 'function' ? onREJECTED : () => {};
if (this.status === myPromise.PENDING) {
this.resolveCallbacks.push(onFULFILLED);
this.rejectCallbacks.push(onREJECTED);
}
if (this.status === myPromise.FULFILLED) {
setTimeout(() => {
onFULFILLED(this.result);
})
}
if (this.status === myPromise.REJECTED) {
setTimeout(() => {
onREJECTED(this.result);
});
}
})
}
}
console.log(1);
let mp = new myPromise((resolve, reject) => {
console.log(2);
setTimeout(() => {
resolve('haha')
console.log(4);
});
})
mp.then((res) => {
console.log(res);
}, (err) => {
console.log(err);
})
console.log(3);
|