源码取自:源码博客
源码:
(function (factory, global) {
if (typeof module === 'object' && typeof module.export === 'object') {
module.export = factory(global);
} else if (typeof define === 'function' && (define.cmd || define.amd)) {
factory(global);
} else {
factory(global);
}
})(function (global, undefined) {
class Promise {
constructor(executor) { //executor执行器
this.status = 'pending'; //默认状态:等待
this.value = undefined; //成功的值
this.reason = undefined //失败的值
this.callBacks = []; //暂存后续的执行
let resolve = (value) => {
if (this.status === 'pending') {
this.status = 'resolved'; //成功
this.value = value;
this.callBacks.forEach(args => this.runCallBacks(args));
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected'; //失败
this.reason = reason;
this.callBacks.forEach(args => this.runCallBacks(args));
}
}
this._abort = reject;
this.runCallBacks = (args) => {
let { onFufilled, onRejected, resolve, reject } = args;
try {
let temp;
if (this.status === 'resolved') {
// 即使回调为空,也不能影响后面的then,catch等方法
temp = onFufilled ? onFufilled(this.value) : this.value;
} else if (this.status === 'rejected') {
temp = onRejected ? onRejected(this.reason) : this.reason;
}
if (temp && typeof temp.then === 'function' && temp instanceof this.constructor) {
temp.then(value => {
resolve(value);
}, reason => {
reject(reason);
});
} else {
resolve(temp);
}
} catch (error) {
reject(error);
}
}
try {
executor(resolve, reject); //默认上执行器执行
} catch (e) { //捕获到异常时,直接走失败
reject(e);
}
}
then(onFufilled, onRejected) {
return new this.constructor((resolve, reject) => {
// 模拟异步(微任务),但是没有直接的定义微任务的api,所以暂用宏任务
setTimeout(() => {
let args = { onFufilled, onRejected, resolve, reject };
if (this.status === 'pending') {
this.callBacks.push(args);
} else {
this.runCallBacks(args);
}
}, 0)
})
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(value => {
return onFinally(value);
}, reason => {
return onFinally(reason)
});
}
abort(reason = 'aborted') {
this._abort(reason);
}
static resolve(data) {
return new this((resovle) => {
resovle(data);
})
}
static reject(data) {
/* 与原生保持一致 */
return new this((resolve, reject) => {
reject(data);
});
}
static all(arr) {
arr = Object.prototype.toString.call([]) === "[object Array]" ? arr : [arr];
let length = arr.length;
if (!length) return;
return new this((resolve, reject) => {
let result = [];
arr.forEach((item, index) => {
return new this(r => r(item))
.then(res => {
result[index] = res;
length--;
length === 0 ? resolve(result) : null;
}, _ => {
reject(_);
})
})
})
}
static race(arr) {
arr = Object.prototype.toString.call([]) === "[object Array]" ? arr : [arr];
let length = arr.length;
if (!length) return;
return new this((resolve, reject) => {
arr.forEach(item => {
new this(r => r(item))
.then(_ => {
resolve(_);
}, _ => {
reject(_);
})
})
})
}
}
global.Promise = Promise;
}, typeof window !== 'undefined' ? window : this);
Promise:
1. 为了实现promise的链式调用,每一次的then,finally或catch后返回的都是一个全新的promise.
2.由于1的原因,状态凝固也只在当前的promise中有效。
3.由于1的原因,promise中的resolveArrs的长度总是<=1,rejectArrs同理。
4.then方法是promise的核心,then的回调的方法:
首先将返回值包装为一个promise,需排除回调方法不是当前promise本身,然后递归执行此promise,至为普通返回值,直接resolve(onResolve),或reject(onReject)
5. catch,finally 为then方法的特殊情况
6. 链式中的then为微任务,需要全部早于当前周期中的所有setTimeout执行,加setTimeout只为模拟效果,和原生的promise有一定的执行顺序差异(js目前没有);
若不加,同时会带来另一个问题:同一周期内此promise的then方法将全部提前于所有原生promise的then方法执行,不过不会出现即使有原生方法又使用此补丁的情况。
7.Promise.resolve(data).then():data为常量或Promise,data为promise时, 状态会被data所改变,then中获取的为promise执行的结果
8.Promise.reject(data):data为常量或Promise,data为promise时,状态会被data所改变,then中获取的为promise本身
来源:oschina
链接:https://my.oschina.net/u/3272730/blog/3116332