上一篇文章 24.Promises/A+ 规范 介绍了Promises/A+ 规范,我们来手动实现一个符合 Promises/A+ 规范的自己的Promise。
根据规范,Promise 共有三种状态 pending
,fulfilled
,rejected
,我们使用 state
来表示 promise 当前的状态,使用 value
来表示当前值
或原因
。当然还有最重要的 then
方法。同时我们还需要一些辅助函数,比如 isFunction
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const PENDING = 0; const FULFILLED = 1; const REJECTED = 2;
function () { this.state = PENDING; this.value = void 0; }
Promise.prototype.then = function (onFulfilled, onRejected) { if (isFunction(onFulfilled) || isFunction(onRejected)) { this.onFulfilled = onFulfilled; this.onRejected = onRejected; } return this; };
function isFunction (func) { return typeof func === 'function'; } function isObject(obj) { return typeof obj === 'object'; }
|
接着,我们定义两个函数,可以将 promise 转换为 fulfilled
或 rejected
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| function doResolve (promise, value) { promise.state = FULFILLED; promise.value = value; if (isFunction(promise.onFulfilled)) { setTimeout(() => { promise.onFulfilled(promise.value); }, 0); } return promise; } function doReject (promise, reason) { promise.state = REJECTED; promise.value = reason; if (isFunction(promise.onRejected)) { setTimeout(() => { promise.onRejected(promise.value); }, 0); }
return promise; }
|
最后,我们还需要一个 resolver,将刚才定义的 doResolve
和 doReject
暴露给 Promise 的构造函数。想想我们平时是怎么 new 一个 Promise的?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function safelyResolveThen(promise, then) { try { then(function (value) { doResolve(promise, value); }, function (reason) { doReject(promise, reason); }) } catch (e) { doReject(promise, e); } }
function (resolver) { this.state = PENDING; this.value = void 0; safelyResolveThen(this, resolver); }
|
到这里,Promise 最核心的功能已经实现。可以很容易地看出,这里 Promise 的底层实现使用了回调(callback)