-
下面通过不同的案列,跟着源码过一遍
-
如果想实现一个自己的promise, 实现一个promise符合A+ 的规范, 请查看
案列一
new Promise(function(resolve, reject) {
resolve('111')
}).then(res => {
console.log(res)
})
简单解释
1. 先进入doResolve 执行里面的 resolve
2. 进入resolve, state 状态变成1 , value赋值
3. 进入then 方法, 执行handle(this, new Handler(onFulfilled, onRejected, res));
4. new Handler(onFulfilled, onRejected, res)) 主要判断onFulfilled, onRejected是否为函数, 并且把新创建的promise 赋值给this.promise
5. 执行handle 里面的 handleResolved(self, deferred);
6. asap 封装的异步,如setTimeout and queueMicrotask 等
7. 执行tryCallOne,然后执行里面的onFulfilled 函数
8. 再次重复resolve的这个流程,然后结束
源码解析
下面可以根据步骤来进行阅读 如 @1 @2 @3 @4 。。。。
'use strict';
var asap = require('asap/raw');
function noop() {}
// States:
//
// 0 - pending
// 1 - fulfilled with _value
// 2 - rejected with _value
// 3 - adopted the state of another promise, _value
var LAST_ERROR = null;
var IS_ERROR = {};
function getThen(obj) {
try {
return obj.then;
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallOne(fn, a) {
try {
return fn(a);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallTwo(fn, a, b) {
try {
fn(a, b);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
module.exports = Promise;
function Promise(fn) {
if (typeof this !== 'object') {
throw new TypeError('Promises must be constructed via new');
}
if (typeof fn !== 'function') {
throw new TypeError('Promise constructor\'s argument is not a function');
}
this._deferredState = 0;
this._state = 0;
this._value = null;
this._deferreds = null;
if (fn === noop) return;
// @1 调用函数fn
doResolve(fn, this);
}
Promise._onHandle = null;
Promise._onReject = null;
Promise._noop = noop;
Promise.prototype.then = function(onFulfilled, onRejected) {
if (this.constructor !== Promise) {
return safeThen(this, onFulfilled, onRejected);
}
var res = new Promise(noop);
// @6 进入then 执行下面的handle new Handler 主要是在res上面添加了onFulfilled onRejected promise
handle(this, new Handler(onFulfilled, onRejected, res));
return res;
};
function safeThen(self, onFulfilled, onRejected) {
return new self.constructor(function (resolve, reject) {
var res = new Promise(noop);
res.then(resolve, reject);
handle(self, new Handler(onFulfilled, onRejected, res));
});
}
function handle(self, deferred) {
while (self._state === 3) {
self = self._value;
}
if (Promise._onHandle) {
Promise._onHandle(self);
}
if (self._state === 0) {
if (self._deferredState === 0) {
self._deferredState = 1;
self._deferreds = deferred;
return;
}
if (self._deferredState === 1) {
self._deferredState = 2;
self._deferreds = [self._deferreds, deferred];
return;
}
self._deferreds.push(deferred);
return;
}
// @7 状态是state === 1 直接进入到下面handleResolved 方法
handleResolved(self, deferred);
}
function handleResolved(self, deferred) {
// @8 asap 采用异步的 如setTimeout and queueMicrotask 等
asap(function() {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
// 补充: 如果 then传进来的只是空, 默认return 当前的值 到下一个then 里面
// 如 Promise.resolve('111').then().then(res => {console.log(res)}) 会打印出 111
if (self._state === 1) {
resolve(deferred.promise, self._value);
} else {
reject(deferred.promise, self._value);
}
return;
}
// @9 当前cd 存在 执行tryCallOne tryCallOne里面执行的函数如果报错,ret 回等于 IS_ERROR 执行下面的 reject, 否则执行resolve
// 因为当前案列后面没有接入then, 只会再次重复执行一下resolve 的过程
var ret = tryCallOne(cb, self._value);
if (ret === IS_ERROR) {
reject(deferred.promise, LAST_ERROR);
} else {
resolve(deferred.promise, ret);
}
});
}
function resolve(self, newValue) {
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self) {
return reject(
self,
new TypeError('A promise cannot be resolved with itself.')
);
}
if (
newValue &&
(typeof newValue === 'object' || typeof newValue === 'function')
) {
var then = getThen(newValue);
if (then === IS_ERROR) {
return reject(self, LAST_ERROR);
}
if (
then === self.then &&
newValue instanceof Promise
) {
self._state = 3;
self._value = newValue;
finale(self);
return;
} else if (typeof then === 'function') {
doResolve(then.bind(newValue), self);
return;
}
}
// @4 当前案列不会进入if 里面 state 变成1 fulfill, 和赋值到value
self._state = 1;
self._value = newValue;
finale(self);
}
function reject(self, newValue) {
self._state = 2;
self._value = newValue;
if (Promise._onReject) {
Promise._onReject(self, newValue);
}
finale(self);
}
function finale(self) {
// @5 当前案列 _deferredState还是0, 所以不会执行, 进入then
if (self._deferredState === 1) {
handle(self, self._deferreds);
self._deferreds = null;
}
if (self._deferredState === 2) {
for (var i = 0; i < self._deferreds.length; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
}
function Handler(onFulfilled, onRejected, promise){
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, promise) {
var done = false;
// @2 执行函数fn
var res = tryCallTwo(fn, function (value) {
if (done) return;
done = true;
// @3 执行resolve
resolve(promise, value);
}, function (reason) {
if (done) return;
done = true;
reject(promise, reason);
});
if (!done && res === IS_ERROR) {
done = true;
reject(promise, LAST_ERROR);
}
}
案列二
new Promise(function (resolve, reject) {
resolve(1);
})
.then((res) => {
console.log(res);
return new Promise(function (resolve1, reject1) {
resolve1(res + 1);
});
})
.then((res) => {
console.log(res);
});
简单解析
// 分为4个步骤
// 1. 第一个promise的执行 resolve ==》 @1 - @4
// 2. 第一个then
同步 ==》 @5 - @7
异步 ==》 @10 - @15
// 3.第一个then里面的回调函数的promise的执行 ==》 @16 - @21
// 4.第二个then的执行 @8 - @9
下面是源码根据案列的步骤解析
源码解析
var asap = function (fn) {
setTimeout(function () {
fn();
}, 0);
};
function noop() {}
// States:
//
// 0 - pending
// 1 - fulfilled with _value
// 2 - rejected with _value
// 3 - adopted the state of another promise, _value
//
// once the state is no longer pending (0) it is immutable
// All `_` prefixed properties will be reduced to `_{random number}`
// at build time to obfuscate them and discourage their use.
// We don't use symbols or Object.defineProperty to fully hide them
// because the performance isn't good enough.
// to avoid using try/catch inside critical functions, we
// extract them to here.
var LAST_ERROR = null;
var IS_ERROR = {};
function getThen(obj) {
try {
return obj.then;
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallOne(fn, a) {
try {
return fn(a);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function tryCallTwo(fn, a, b) {
try {
fn(a, b);
} catch (ex) {
LAST_ERROR = ex;
return IS_ERROR;
}
}
function Promise(fn) {
if (typeof this !== "object") {
throw new TypeError("Promises must be constructed via new");
}
if (typeof fn !== "function") {
throw new TypeError(
"Promise constructor's argument is not a function"
);
}
this._deferredState = 0;
this._state = 0;
this._value = null;
this._deferreds = null;
if (fn === noop) return;
// @1 调用函数fn
// @16 重新执行第三个promise, this = 第三个promise
doResolve(fn, this);
}
Promise._onHandle = null;
Promise._onReject = null;
Promise._noop = noop;
Promise.prototype.then = function (onFulfilled, onRejected) {
if (this.constructor !== Promise) {
return safeThen(this, onFulfilled, onRejected);
}
var res = new Promise(noop);
// @5 第一个then 进入,当前的this 指向的是第一个promise,
// @8 第二个then 进入, 当前的this 指向第二个promise( 上一个then return出来的promise)
// 第二个promise 的状态 是默认的还是没有修改 所以 state = 0 _deferredState = 0
handle(this, new Handler(onFulfilled, onRejected, res));
// @7 第一个then 返回一个promise 标记为第二个promsie
// 第一个then 里面的同步执行完成, 然后会执行第二个then,在此进入then
return res;
};
function safeThen(self, onFulfilled, onRejected) {
return new self.constructor(function (resolve, reject) {
var res = new Promise(noop);
res.then(resolve, reject);
handle(self, new Handler(onFulfilled, onRejected, res));
});
}
function handle(self, deferred) {
while (self._state === 3) {
// @14 第三个promise(第一个then函数回调的promise) 直接覆盖给了 第二个promise(第一个then 自身return出来的promsie)
// self 指向第三个promise
self = self._value;
}
if (Promise._onHandle) {
Promise._onHandle(self);
}
if (self._state === 0) {
if (self._deferredState === 0) {
// @9 第二个then 会执行这里, 并且第二个promise状态的_deferredState = 1, 第二个promise 记录的_deferreds = onFulfilled和onRejected 和(第二个then 返回的Promise,因为下一级没的then, 不会用)
// 第二个then 执行完成,再去执行第一个then 里面的异步handleResolved(第一个的handleResolved)
// @15 第三个promise 的状态全是初始值,第三个promise的_deferredState = 1
// deferreds里面包含了 第二个then 的onfulfill 和 onreject 的回调函数 请参看@13
// 执行回调函数的(第三个promise )的流程 进入XPromise函数 重新执行一遍
self._deferredState = 1;
self._deferreds = deferred;
return;
}
if (self._deferredState === 1) {
self._deferredState = 2;
self._deferreds = [self._deferreds, deferred];
return;
}
self._deferreds.push(deferred);
return;
}
// @6 第一个promise 在resolve 的时候状态state 已经变成了1 不会执行上面的
// handleResolved 执行的是异步, 放在任务队列里面去, 标记为 第一个的handleResolved
// @20 第三个promise的状态是 _state = 1 _deferredState = 1
handleResolved(self, deferred);
}
function handleResolved(self, deferred) {
asap(function () {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
// 补充: 如果 then传进来的只是空, 默认return 当前的值 到下一个then 里面
// 如 Promise.resolve('111').then().then(res => {console.log(res)}) 会打印出 111
if (self._state === 1) {
resolve(deferred.promise, self._value);
} else {
reject(deferred.promise, self._value);
}
return;
}
// @10 第一个promise 记录的状态_state = 1,所以执行cd = deferred.onFulfilled
// 执行 tryCallOne, 返回的 第一个then 回调函数里面的 return出来promise 标记为: 第三个promise
// ret = 第一个then 回调函数里面的 return出来promise 标记为: 第三个promise
// @21 cd = 第二个then 的函数onfulfill , 执行第二个then 的回调函数
// 下面还会去执行 reoslve, 但是没有三个then,所以只会记录第二个then 返回的promise的状态
// 以上的执行过程 就是关于案列二 的已完成
var ret = tryCallOne(cb, self._value);
if (ret === IS_ERROR) {
reject(deferred.promise, LAST_ERROR);
} else {
// @11 deferred 是第一个promise, deferred.promise 是第二个promsie
// ret 是第三个promise
resolve(deferred.promise, ret);
}
});
}
function resolve(self, newValue) {
if (newValue === self) {
return reject(
self,
new TypeError("A promise cannot be resolved with itself.")
);
}
if (
newValue &&
(typeof newValue === "object" || typeof newValue === "function")
) {
var then = getThen(newValue);
if (then === IS_ERROR) {
return reject(self, LAST_ERROR);
}
if (then === self.then && newValue instanceof Promise) {
// @12 当前self 指向的是第二个的promise 请参考@11
// 第二个的promise _state = 3, _deferredState = 1 请参考@9
// newValue 是第三个promise
self._state = 3;
self._value = newValue;
finale(self);
return;
} else if (typeof then === "function") {
doResolve(then.bind(newValue), self);
return;
}
}
self._state = 1;
self._value = newValue;
// @4 第一个promsie 执行的resolve self = 第一个promise, _state = 1, _deferredState = 0, 下面finale 函数不会进入if
// @18 第三个promise的 _state = 1 _deferredState = 1 请参看@15
finale(self);
}
function reject(self, newValue) {
self._state = 2;
self._value = newValue;
if (Promise._onReject) {
Promise._onReject(self, newValue);
}
finale(self);
}
function finale(self) {
if (self._deferredState === 1) {
// @13 当前self 指向的是第二个的promise self._deferreds里面包含了 第二个then 的onfulfill 和 onreject 的回调函数
// @19 self = 第三个promise, self._deferreds里面包含了 第二个then 的onfulfill 和 onreject 的回调函数 请参考@15
handle(self, self._deferreds);
self._deferreds = null;
}
if (self._deferredState === 2) {
for (var i = 0; i < self._deferreds.length; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
}
function Handler(onFulfilled, onRejected, promise) {
this.onFulfilled = typeof onFulfilled === "function" ? onFulfilled : null;
this.onRejected = typeof onRejected === "function" ? onRejected : null;
this.promise = promise;
}
function doResolve(fn, promise) {
var done = false;
// @2 执行函数fn
var res = tryCallTwo(
fn,
function (value) {
if (done) return;
done = true;
// @3 执行resolve
// @17 执行第三个promise 的 resolve
resolve(promise, value);
},
function (reason) {
if (done) return;
done = true;
reject(promise, reason);
}
);
if (!done && res === IS_ERROR) {
done = true;
reject(promise, LAST_ERROR);
}
}