Open chenyinkai opened 6 years ago
简单版本的 Promise 实现,只有 then 方法
Promise
then
function MyPromise(executor){ let self = this self.status = 'pending' // Promise当前的状态 self.data = undefined // Promise的值 self.onResolvedCallback = [] // Promise resolve时的回调函数集,因为在Promise结束之前有可能有多个回调添加到它上面 self.onRejectedCallback = [] // Promise reject时的回调函数集,因为在Promise结束之前有可能有多个回调添加到它上面 let resolve = (value) => { if (self.status === 'pending') { self.status = 'resolved' self.data = value for (let i = 0; i < self.onResolvedCallback.length; i++) { self.onResolvedCallback[i](value) } } } let reject = (reason) => { if (self.status === 'pending') { self.status = 'rejected' self.data = reason for (let i = 0; i < self.onRejectedCallback.length; i++) { self.onRejectedCallback[i](reason) } } } try { // 考虑到执行executor的过程中有可能出错,所以我们用try/catch块给包起来,并且在出错后以catch到的值reject掉这个Promise executor(resolve, reject) // 执行executor } catch (e) { reject(e) } } MyPromise.prototype.then = function (onResolved, onRejected) { let self = this let promise2 // 根据标准,如果then的参数不是function,则我们需要忽略它,此处以如下方式处理 onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value } onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { throw reason } if (self.status === 'resolved') { // 如果promise1(此处即为this/self)的状态已经确定并且是resolved,我们调用onResolved // 因为考虑到有可能throw,所以我们将其包在try/catch块里 return promise2 = new MyPromise(function (resolve, reject) { try { let result = onResolved(self.data) if (result instanceof Promise) { // 如果onResolved的返回值是一个Promise对象,直接取它的结果做为promise2的结果 result.then(resolve, reject) } resolve(result) // 否则,以它的返回值做为promise2的结果 } catch (e) { reject(e) // 如果出错,以捕获到的错误做为promise2的结果 } }) } if (self.status === 'rejected') { return promise2 = new MyPromise(function (resolve, reject) { try { let result = onRejected(self.data) if (result instanceof Promise) { result.then(resolve, reject) } } catch (e) { reject(e) } }) } if (self.status === 'pending') { return promise2 = new MyPromise(function (resolve, reject) { self.onResolvedCallback.push(function (value) { try { let result = onResolved(self.data) if (result instanceof Promise) { result.then(resolve, reject) } } catch (e) { reject(e) } }) self.onRejectedCallback.push(function (reason) { try { let result = onRejected(self.data) if (result instanceof Promise) { result.then(resolve, reject) } } catch (e) { reject(e) } }) }) } }
测试
const MyPromiseTest = () => { return new MyPromise((resolve, reject) => { setTimeout(() => { let num = Math.random(); resolve(num); }, 3000); }) } MyPromiseTest().then((result) => { console.log(result); })
3 秒后输出随机数
3 秒后输出随机数