https://github.com/taylorhakes/promise-polyfill
function Promise(fn) {
if (!(this instanceof Promise))
throw new TypeError('Promises must be constructed via new');
if (typeof fn !== 'function') throw new TypeError('not a function');
/**
* 0: pending
* 1: resolve
* 2: reject
* 3: res(p)中p为promise类型
*/
this._state = 0;
/** 是否处理完成 */
this._handled = false;
/** 当前promise的value值 */
this._value = undefined;
/** 保存obj,obj包含3个参数:
* 当前promise的onFulfilled和onRejected回调方法
* 当前promise的完成后要执行的promise
*/
this._deferreds = [];
doResolve(fn, this);
}
执行Promise构造时的参数。且如果执行出错,则直接reject
new Promise((res, rej) => {
setTimeout(() => {
res();
}, 0)
});
function doResolve(fn, self) {
var done = false;
try {
fn(
// 上面代码中res()时执行
function(value) {
if (done) return;
done = true;
resolve(self, value);
},
// 上面代码中rej()时执行
function(reason) {
if (done) return;
done = true;
reject(self, reason);
}
);
} catch (ex) {
if (done) return;
done = true;
reject(self, ex);
}
}
可以看到是同步执行的,所以下面代码依次输出1,2,3
new Promise(() => {
console.log(1);
});
console.log(2);
setTimeout(() => {
console.log(3);
}, 0);
Promise.prototype.then = function(onFulfilled, onRejected) {
var prom = new this.constructor(noop);
// handler存储调用then的promise及then的参数
var handler = new Handler(onFulfilled, onRejected, prom);
handle(this, handler);
// 返回prom,即下一个then的this对象
return prom;
};
function Handler(onFulfilled, onRejected, promise) {
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
根据当前promise的状态处理:
当前promise的值是promise,则取最内层的promise值为作为当前promise
当前promise为pending状态,将其调用then时then的参数及自身存到自己的_deferreds上,所以then return prom会在then的调用链上形成promise内有_deferreds,_deferreds内有promise的循环
当前promise为resolve(1)或reject(2)状态,取对应的回调执行
function handle(self, deferred) {
while (self._state === 3) {
self = self._value;
}
// 将then的参数存放在then的调用者的_deferreds中
if (self._state === 0) {
self._deferreds.push(deferred);
return;
}
self._handled = true;
// resolve后当前promise的状态为1,reject后为2,且要在下个事件循环中完成回调
Promise._immediateFn(function() {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
return;
}
var ret;
try {
ret = cb(self._value);
} catch (e) {
reject(deferred.promise, e);
return;
}
// deferred.promise:取deferred上的promise,及下一个then的调用者
resolve(deferred.promise, ret);
});
}
关键代码:
将当前promise的状态改为1(resolve),执行final,
self._state = 1;
self._value = newValue;
finale(self);
function finale(self) {
if (self._state === 2 && self._deferreds.length === 0) {
Promise._immediateFn(function() {
if (!self._handled) {
Promise._unhandledRejectionFn(self._value);
}
});
}
// 取当前promise的_deferreds,处理当前promise的状态
for (var i = 0, len = self._deferreds.length; i < len; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
Promise的就是根据状态进行处理的过程,最关键的是then方法的返回参数并不是this,因为每个then或catch的状态需要分开处理
new Promise((res) => { res(); }) // p1
.then(f1) // p2
.then(f2) // p3
将上面代码中调用每行then的promise实例分别标记为p1,p2,p3,当然p1自己就是promise
p2对应的line执行时,调用者是p1,在p1实例的_deferreds中存储f1和p2的实例,且返回p2
p3对应的line执行时,调用者是p2,所以在p2实例的_deferreds中存储f2和p3的实例,且返回p3