再来看下我们的then函数。then函数的两个参数,onFulfilled表示当promise异步操作成功时调用的函数,onRejected表示当promise异步操作失败时调用的函数。假如我们调用then的时候,promise已经执行完成了(当任务是个同步任务时),我们可以直接根据实例的状态来执行相应的函数。假如promise的状态还是PENDING, 那我们就将onFulfilled和onRejected直接存储到chained这个变量当中,等promise执行完再调用。
constructor(executor) { ... this.state = 'PENDING'; // chained用来储存promise执行完成以后,需要被依次调用的一系列函数 this.chained = []; const resolve = (result) => { this.state = 'FULFILLED'; this.value = result; // promise已经执行成功了,可以依次调用.then()函数里的onFulfilled函数了 for (const { onFulfilled } of this.chained) { onFulfilled(res); } } ... } then(onFulfilled, onRejected) { if (this.state === 'FULFILLED') { onFulfilled(this.value); } else if (this.state === 'REJECTED') { onRejected(this.value); } else { this.$chained.push({ onFulfilled, onRejected }); } }
这样我们就完成了一个CutePromise的创建,下面是完整代码,大家可以复制代码到控制台测试一下:
class CutePromise { constructor(executor) { if (typeof executor !== 'function') { throw new Error('Executor must be a function'); } this.state = 'PENDING'; this.chained = []; const resolve = res => { if (this.state !== 'PENDING') { return; } this.state = 'FULFILLED'; this.internalValue = res; for (const { onFulfilled } of this.chained) { onFulfilled(res); } }; const reject = err => { if (this.state !== 'PENDING') { return; } this.state = 'REJECTED'; this.internalValue = err; for (const { onRejected } of this.chained) { onRejected(err); } }; try { executor(resolve, reject); } catch (err) { reject(err); } } then(onFulfilled, onRejected) { if (this.state === 'FULFILLED') { onFulfilled(this.internalValue); } else if (this.$state === 'REJECTED') { onRejected(this.internalValue); } else { this.chained.push({ onFulfilled, onRejected }); } } }
提供一下测试代码:
let p = new CutePromise(resolve => { setTimeout(() => resolve('Hello'), 100); }); p.then(res => console.log(res)); p = new CutePromise((resolve, reject) => { setTimeout(() => reject(new Error('woops')), 100); }); p.then(() => {}, err => console.log('Async error:', err.stack)); p = new CutePromise(() => { throw new Error('woops'); }); p.then(() => {}, err => console.log('Sync error:', err.stack));
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
您可能感兴趣的文章: