大致思路:
1、Promise的构造函数,只有一个函数参数resolver(resolve,reject),而函数参数resolver的两个参数都是函数参数,第一个参数resolve表示处理成功执行的函数,reject表示失败执行的函数
在构造函数中的属性有state(保存当前promise的状态);value(保存resolve或发生reject的错误原因);queue(Array,同一个promise可以多次调用then方法,这里是保存调用then方法之后生成的promise对象及其对应的resolve reject函数)
构造函数主要职责有:
a)初始化Promise的状态,this.state = PENDING
b)初始化resolve或reject的参数值,this.value = void 0
c)初始化then()注册的回调函数,this.queue = []
d)立即执行resolver(resolve,reject),即调用函数safelyResolveThen(self, then)-
立即执行resolver(resolve,reject)被封装在函数safelyResolveThen(self, then)----self为当前promise对象,resolver=then
这里就是执行函数resolver.
通过闭包对变量called的持有,使变量一直保存在内存中,达到resolve reject只执行一次,即同一个promise的状态由pending=>fulfilled或者pending => rejected只发生一次
在函数safelyResolveThen(self, then)里面调用了全局函数doResolve(self, value)和doReject(self, error)
doResolve(self, value)—doResolve 结合 safelyResolveThen 使用,不断地解包 promise 对象后,当值不是一个thenable对象时设置 promise 的状态和值。解包promise对象使用了方法getThen(value)。同时对queue遍历,通知queue中的每个promise的子promise,子promise 根据传入的值设置自己的状态和值
getThen(value)----如果value是一个thenable对象函数,那么就返回一个函数(在函数内,通过apply将value.then方法的作用域改成value,并执行then方法)
doReject(self, error) -----设置 promise的state为 REJECTED,value 为 error。同时遍历queue,对每个成员对象调用 callRejected,通知子 promise,子 promise 根据传入的错误设置自己的状态和值
2、Promise.prototype.then(onFulfilled, onRejected)----两个参数,成功时执行的回调函数onFulfilled,失败时执行的回调函数
onRejected。返回值是一个新生成的promise对象
根据当前promise的state状态来做相应的处理:
1)存在值穿透问题,即then方法没有参数或者参数为一个值
2)state不为PENDING,则执行unwrap(promise, resolver, this.value)。判断state为FULFILLED则resolver=onFulfilled,为REJECTED则resolver=onRejected。
3)否则promise的状态没有改变,即state=PENDIGN,将生成的promise对象和对应的onFulfilled, onRejected加入到当前promise的回调队列queue里面
unwrap(promise, resolver, this.value)----调用immediate.js将同步代码生成异步代码。同时执行回调函数,并验证处理的结果returnValue,如果为promise本身则抛出错误,否则调用doResolve(promise, returnValue)
Promise的静态方法
3、Promise.resolve(value)------返回一个promise对象;
a)value是一个promise对象则直接返回value;否则调用doResolve函数
b)value是一个thenable对象,将其转为promise对象,立即执行then方法,该promise的状态由这个thenable对象的then方法的具体设置而定;
c)value是一个原始值,或者是一个不具有then方法的对象,返回promise对象,状态为resolve
d)不带任何参数,直接返回一个promise对象
4、Promise.reject(reason)----返回一个promise对象;该实例的状态为rejected
直接返回doReject(promise, reason)处理后的结果
5、Promise.all(iterable)-------接受一个参数,返回一个promise。将多个promise封装成一个promise
返回promise的回调函数的参数值:
a)只有iterable中所有的promise对象的状态都变成fulfilled的时候,返回promise的状态才为fulfilled,且传递给返会promise对象的回调函数的参数为Array,元素由这些promise resolve之后的值组成
b)否则返回第一个被reject的实例的返回值,作为返回promise的回到函数的参数
6、Promise.race(iterable)-------接受一个参数,返回一个promise。将多个promise封装成一个promise
返回promise的回调函数的参数值:
a)返回第一个状态先改变的promise对象处理之后的值
'use strict';
var immediate = require('immediate'); //用immediate.js库将同步代码装成异步代码
function INTERNAL() {}
function isFunction(func) {
return typeof func === 'function';
}
function isObject(obj) { //Array Object Null Set Map 都为true
return typeof obj === 'object';
}
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
var PENDING = 0; //控制promise对象的状态
var FULFILLED = 1;
var REJECTED = 2;
module.exports = Promise; //输出模块
function Promise(resolver) { //Promise构造函数
if (!isFunction(resolver)) {
throw new TypeError('resolver must be a function');
}
this.state = PENDING; //初始化promise的状态为PENDIGN
this.value = void 0; //初始化resolve或reject的参数值
this.queue = []; //then方法可被同一个promise对象多次调用,用于注册新生成的promise对象
if (resolver !== INTERNAL) {
safelyResolveThen(this, resolver); //立即执行传进来的resolver函数
}
}
function safelyResolveThen(self, then) {
var called = false; //called被用在闭包里面,使得它的值一直保存在内存中,用于promise的
try { //called 控制 resolve 或 reject 只执行一次,多次调用没有任何作用
then(function (value) {
if (called) {
return;
}
called = true;
doResolve(self, value);
}, function (error) {
if (called) {
return;
}
called = true;
doReject(self, error);
});
} catch (error) {
if (called) {
return;
}
called = true;
doReject(self, error);
}
}
function doResolve(self, value) { //doResolve 结合 safelyResolveThen 使用,不断地解包
// promise 对象后,设置 promise 的状态和值
try {
var then = getThen(value);
if (then) {
safelyResolveThen(self, then); //value是一个thenable对象,则递归遍历直到是一个值
} else {
self.state = FULFILLED;
self.value = value;
self.queue.forEach(function (queueItem) { //对queue遍历,执行当前promise对应的callFulfilled()
queueItem.callFulfilled(value); //callFulfilled通知子 promis, 子promise 根据传入的值设置自己的状态和值。
});
}
return self; //返回promise对象
} catch (error) {
return doReject(self, error);
}
}
function doReject(self, error) { // 设置 promise的state为 REJECTED,value 为 error
self.state = REJECTED;
self.value = error;
self.queue.forEach(function (queueItem) {
queueItem.callRejected(error); // callRejected通知子 promise,子 promise 根据传入的错误设置自己的状态和值
});
return self; //返回当前promise对象
}
function getThen(obj) { //传入的obj不为空,然后访问obj是否有then方法,有就返回obj.then(),否则为undefined
var then = obj && obj.then; // obj是一个thenable对象
if ( obj && ( isObject(obj) || isFunction(obj) ) && isFunction(then) ) {
return function appyThen() {
then.apply(obj, arguments);
};
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
if( !isFunction(onFulfilled) && this.state === FULFILLED ||
!isFunction(onRejected) && this.state === REJECTED) {
return this; //实现了值穿透
}
// 生成新的promise对象
var promise = new this.constructor(INTERNAL);
// promise 的状态改变了,则调用 unwrap
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.value);
} else {
//promise对象状态没有改变,将生成的promise对象加入到当前promise的回调队列queue里面
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
Promise.prototype.catch = function (onRejected) {
return this.then(null, onRejected);
};
function unwrap(promise, func, value) { //解包,参数分别为子promise 父promise的then的回调onFulfilled/onRejected
immediate(function () { // immediate()将同步代码变成异步代码 //父 promise 的值(正常值/错误)
var returnValue;
try { //捕获promise.then() promise.catch()内部的异常
returnValue = func(value);
} catch (error) {
return doReject(promise, error);
}
if (returnValue === promise) { //返回的值不能是 promise 本身,否则会造成死循环
doReject(promise, new TypeError('Cannot resolve promise with itself'));
} else {
doResolve(promise, returnValue);
}
});
}
// 类QueueItem具有的属性this.promise this.callFulfilled this.callRejected
function QueueItem(promise, onFulfilled, onRejected) {
this.promise = promise;
this.callFulfilled = function (value) {
doResolve(this.promise, value); //设置当前promise的状态和值
};
this.callRejected = function (error) {
doReject(this.promise, error);
};
if (isFunction(onFulfilled)) {
this.callFulfilled = function (value) {
unwrap(this.promise, onFulfilled, value);
};
}
if (isFunction(onRejected)) {
this.callRejected = function (error) {
unwrap(this.promise, onRejected, error);
};
}
}
Promise.resolve = resolve;
function resolve(value) { //返回一个promise对象
if (value instanceof this) { //当 Promise.resolve 参数是一个 promise 时,直接返回该值
return value;
}
return doResolve(new this(INTERNAL), value); //否则调用doResolve函数
}
Promise.reject = reject;
function reject(reason) { //返回一个promise对象。
var promise = new this(INTERNAL);
return doReject(promise, reason); //调用doReject
}
Promise.all = all;
function all(iterable) {
var self = this;
if (!isArray(iterable)) {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var values = new Array(len);
var resolved = 0;
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
allResolver(iterable[i], i);
}
return promise;
function allResolver(value, i) {
self.resolve(value).then(resolveFromAll, function (error) {
if (!called) {
called = true;
doReject(promise, error);
}
});
function resolveFromAll(outValue) {
values[i] = outValue;
if (++resolved === len && !called) {
called = true;
doResolve(promise, values);
}
}
}
}
Promise.race = race;
function race(iterable) {
var self = this;
if (!isArray(iterable)) {
return this.reject(new TypeError('must be an array'));
}
var len = iterable.length;
var called = false;
if (!len) {
return this.resolve([]);
}
var i = -1;
var promise = new this(INTERNAL);
while (++i < len) {
resolver(iterable[i]);
}
return promise;
function resolver(value) {
self.resolve(value).then(function (response) {
if (!called) {
called = true;
doResolve(promise, response);
}
}, function (error) {
if (!called) {
called = true;
doReject(promise, error);
}
});
}
}