====== 差别 ======
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
javascript_手写promise [2022/03/18 16:04] 若愚 |
javascript_手写promise [2022/04/06 22:33] (当前版本) 若愚 |
||
---|---|---|---|
行 1: | 行 1: | ||
# 手写Promise | # 手写Promise | ||
- | 代码比较短的实现 | + | |
```javascript | ```javascript | ||
- | /** | + | const PENDING = " |
- | * 1. new Promise时,需要传递一个 executor 执行器,执行器立刻执行 | + | const FULFILLED = " |
- | * 2. executor 接受两个参数,分别是 resolve 和 reject | + | const REJECTED = " |
- | * 3. promise 只能从 pending 到 rejected, 或者从 pending 到 fulfilled | + | |
- | * 4. promise 的状态一旦确认,就不会再改变 | + | |
- | * 5. promise 都有 then 方法,then 接收两个参数,分别是 promise 成功的回调 onFulfilled, | + | |
- | | + | |
- | * 6. 如果调用 then 时,promise已经成功,则执行 onFulfilled,并将promise的值作为参数传递进去。 | + | |
- | | + | |
- | | + | |
- | * 7. then 的参数 onFulfilled 和 onRejected 可以缺省 | + | |
- | * 8. promise 可以then多次,promise 的then 方法返回一个 promise | + | |
- | * 9. 如果 then 返回的是一个结果,那么就会把这个结果作为参数,传递给下一个then的成功的回调(onFulfilled) | + | |
- | * 10. 如果 then 中抛出了异常,那么就会把这个异常作为参数,传递给下一个then的失败的回调(onRejected) | + | |
- | * 11.如果 then 返回的是一个promise,那么会等这个promise执行完,promise如果成功, | + | |
- | | + | |
- | */ | + | |
- | const PENDING = ' | + | function |
- | const FULFILLED = ' | + | |
- | const REJECTED = ' | + | } |
- | function | + | |
- | | + | |
- | | + | |
- | self.onFulfilled = []; | + | |
- | self.onRejected = []; | + | |
- | | + | function |
- | if (self.status === PENDING) { | + | throw err; |
- | self.status = FULFILLED; | + | } |
- | | + | |
- | self.onFulfilled.forEach(fn => fn()); | + | |
- | } | + | |
- | | + | |
- | | + | function |
- | if (self.status | + | if (promise2 |
- | | + | |
- | | + | |
- | self.onRejected.forEach(fn => fn()); | + | |
} | } | ||
- | + | let called; | |
- | | + | |
- | | + | |
- | } catch (e) { | + | let then = x.then; |
- | reject(e); | + | if (typeof then === " |
+ | then.call( | ||
+ | x, | ||
+ | (y) => { | ||
+ | if (called) return; | ||
+ | called = true; | ||
+ | resolvePromise(promise2, | ||
+ | }, | ||
+ | (r) => { | ||
+ | if (called) return; | ||
+ | called = true; | ||
+ | reject(r); | ||
+ | } | ||
+ | ); | ||
+ | } else { | ||
+ | resolve(x); | ||
+ | } | ||
+ | | ||
+ | if (called) return; | ||
+ | called = true; | ||
+ | | ||
+ | } | ||
+ | } else { | ||
+ | resolve(x); | ||
} | } | ||
} | } | ||
- | Promise2.prototype.then = function | + | class Promise { |
- | | + | constructor(executor) { |
- | | + | |
- | let self = this; | + | this.value |
- | let promise2 | + | this.reason |
- | if (self.status === FULFILLED) { | + | this.resolveCallbacks |
+ | this.rejectCallbacks | ||
+ | |||
+ | let resolve | ||
+ | if (this.status | ||
+ | this.status = FULFILLED; | ||
+ | | ||
+ | | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | | ||
+ | if (this.status === PENDING) { | ||
+ | this.status = REJECTED; | ||
+ | this.reason = reason; | ||
+ | this.rejectCallbacks.forEach((fn) => fn()); | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | try { | ||
+ | executor(resolve, | ||
+ | } catch (error) { | ||
+ | reject(error); | ||
+ | } | ||
+ | } | ||
- | setTimeout(() => { | + | then(onFulfilled, |
- | try { | + | |
- | let x = onFulfilled(self.value); | + | |
- | resolvePromise(promise2, | + | let promise2 |
- | } catch (e) { | + | if (this.status === FULFILLED) { |
- | reject(e); | + | |
- | } | + | |
- | }); | + | |
- | | + | |
- | setTimeout(() | + | |
- | try { | + | |
- | | + | |
- | resolvePromise(promise2, x, resolve, reject); | + | |
- | } catch (e) { | + | |
- | reject(e); | + | |
- | } | + | |
- | | + | |
- | } else if (self.status === PENDING) { | + | |
- | self.onFulfilled.push(() => { | + | |
setTimeout(() => { | setTimeout(() => { | ||
try { | try { | ||
- | let x = onFulfilled(self.value); | + | let x = onFulfilled(this.value); |
resolvePromise(promise2, | resolvePromise(promise2, | ||
} catch (e) { | } catch (e) { | ||
reject(e); | reject(e); | ||
} | } | ||
- | }); | + | }, 0); |
- | }); | + | } |
- | | + | |
+ | | ||
setTimeout(() => { | setTimeout(() => { | ||
try { | try { | ||
- | let x = onRejected(self.reason); | + | let x = onRejected(this.reason); |
resolvePromise(promise2, | resolvePromise(promise2, | ||
} catch (e) { | } catch (e) { | ||
reject(e); | reject(e); | ||
} | } | ||
- | }); | + | }, 0); |
- | | + | } |
- | } | + | |
- | }); | + | |
- | return promise2; | + | |
- | } | + | |
- | function resolvePromise(promise2, x, resolve, reject) { | + | if (this.status |
- | let self = this; | + | |
- | if (promise2 | + | |
- | | + | try { |
- | } | + | let x = onFulfilled(this.value); |
- | if (x && typeof x === ' | + | resolvePromise(promise2, |
- | let used; // | + | } catch (e) { |
- | | + | |
- | let then = x.then; | + | } |
- | if (typeof then === ' | + | |
- | then.call(x, (y) => { | + | |
- | if (used) return; | + | |
- | used = true; | + | |
- | | + | |
- | }, (r) => { | + | |
- | | + | |
- | used = true; | + | |
- | | + | |
}); | }); | ||
- | }else{ | + | this.rejectCallbacks.push(() => { |
- | | + | |
- | | + | try { |
- | | + | let x = onRejected(this.reason); |
+ | | ||
+ | } catch (e) { | ||
+ | reject(e); | ||
+ | } | ||
+ | }, 0); | ||
+ | }); | ||
} | } | ||
- | } catch (e) { | + | }); |
- | if (used) return; | + | |
- | used = true; | + | |
- | reject(e); | + | |
- | | + | |
- | } else { | + | |
- | resolve(x); | + | |
} | } | ||
} | } | ||
+ | ``` | ||
+ | 更标准的实现 | ||
+ | https:// | ||
- | |||
- | var p1 = new Promise2((r, | ||
- | console.log(' | ||
- | setTimeout(()=> | ||
- | r(1) | ||
- | }, 1000) | ||
- | }) | ||
- | console.log(p1) | ||
- | var p2 = p1.then(v => { | ||
- | console.log(' | ||
- | console.log(v+1) | ||
- | return v+1 | ||
- | }) | ||
- | console.log(p2) | ||
- | var p3 = p2.then(v => { | ||
- | console.log(' | ||
- | console.log(v+1) | ||
- | }) | ||
- | console.log(p3) | ||
- | ``` | ||
- | |||
- | 在控制台 查看 p1, p2, p3的值 | ||
- | |||
- | ## 来源 | ||
- | -[Promise的源码实现(完美符合Promise/ | ||