这里超级安利你们去看《深刻浅出nodejs》4.3.2 章节,别问我为啥总是安利这个,问就真的好看啊!!javascript
promise的规范有一大堆,可是es6采用了Promise A+ 规范html
相关文档 Promise A+规范的友情解释连接 规范说明英文版java
相信你们看完上面给的那个链接已经对整个promise的执行过程都有个了解了。 这里总结下node
如下为菜狗子根据规范约定实(chao)现(xi),有错欢迎指出。git
大佬们封装的promise实现测试工具,有实现完成的,能够用这个测试下是否符合标准。es6
大佬们封装好的例子想要看更多的,能够看这里。菜狗子的实现参考其中belofte.js为方便理解(就是懒)砍掉了许多类型判断。github
注释写的比我多,讲的比我细致的一篇文章promise
const PENDING = "Pending";
const FULFILLED = "Fulfilled";
const REJECTED = "Rejected";
const root = typeof window === "undefined" ? global : window;
const isFunction = data => typeof data === "function";
const isMyPromise = fn => fn instanceof MyPromise;
const isObject = data =>
data && (typeof data === "object" || typeof data === "function");
// 由于promise是微任务,咱们尽量的去模拟
const nextTick = (function() {
if (typeof root.process === "object" && isFunction(root.process.nextTick)) {
// node环境
return function(fn) {
// process.nextTick 是微任务
root.process.nextTick(fn);
};
} else {
// 浏览器环境
return function(fn) {
// setTimeout 是宏任务
root.setTimeout(fn, 0);
};
}
})();
// 将promise由中间态到终态
const promiseResolutionProcedure = function(promise, result, async = true) {
if (promise === result) {
/** * 由于promise 若是收到的value是一个promise会等待他的结果。 * 因此若是接受到的value是自己就递归了。 * * @see https://promisesaplus.com/ 2.3.1 条规定 */
promise._reject(new TypeError("Chaining cycle detected for promise"));
return;
}
// 若是接收到的是个promise
if (isMyPromise(result)) {
switch (result._state) {
case FULFILLED: {
nextTick(function() {
promise._resolve(result._value);
});
break;
}
case REJECTED: {
nextTick(function() {
promise._reject(result._reason);
});
break;
}
case PENDING: {
const _resolve = result._resolve;
const _reject = result._reject;
result._resolve = function(value) {
_resolve.call(result, value);
promise._resolve(value);
}.bind(result);
result._reject = function(reason) {
_reject.call(result, reason);
promise._reject(reason);
}.bind(result);
break;
}
}
return;
}
// 若是接受到的是个thenable 对象
if (isObject(result) && isFunction(result.then)) {
/** * 屡次调用只有第一次有效 * * @see https://promisesaplus.com/ 2.3.3.3.3 条规定 */
let flag = false;
const _resolve = function(value) {
if (flag) {
return;
}
flag = true;
promiseResolutionProcedure(promise, value);
};
const _reject = function(reason) {
if (flag) {
return;
}
flag = true;
promise._reject(reason);
};
const thenTemp = function() {
try {
result.then(_resolve, _reject);
} catch (error) {
_reject(error);
}
};
if (async) {
nextTick(thenTemp);
} else {
thenTemp();
}
return;
}
promise._resolve(result);
return;
};
class MyPromise {
constructor(resolver) {
if (!isFunction(resolver)) {
throw new TypeError("Promise resolver undefined is not a function");
}
/** @type { PENDING | FULFILLED | REJECTED} */
this._state = PENDING;
this._value = undefined;
this._reason = undefined;
this._isPromise = true;
/** * 由于同一个promise能够被then 屡次。 * 这里的屡次不是指链式调用!!!! * 这里理解了很久TAT */
this._resolveFnQueues = [];
this._rejectFnQueuse = [];
promiseResolutionProcedure(this, { then: resolver }, false);
}
_resolve(value) {
if (this._state !== PENDING) {
return;
}
this._state = FULFILLED;
this._value = value;
if (this._resolveFnQueues.length) {
nextTick(() => {
this._resolveFnQueues.forEach(cb => cb(value));
this._resolveFnQueues.length = 0;
this._rejectFnQueuse.length = 0;
});
}
}
_reject(reason) {
if (this._state !== PENDING) {
return;
}
this._state = FULFILLED;
this._reason = reason;
if (this._rejectFnQueuse.length) {
nextTick(() => {
this._rejectFnQueuse.forEach(cb => cb(reason));
this._resolveFnQueues.length = 0;
this._rejectFnQueuse.length = 0;
});
}
}
// then注册一个监听,在这个promise onFulfilled 或者 onRejected
then(onFulfilled, onRejected) {
onFulfilled = isFunction(onFulfilled) ? onFulfilled : MyPromise.resolve;
onRejected = isFunction(onRejected) ? onRejected : MyPromise.reject;
const chainPromise = new MyPromise(function() {});
const nextOnFulfilled = function(value) {
let result;
try {
result = onFulfilled(value);
promiseResolutionProcedure(chainPromise, result);
} catch (error) {
chainPromise._reject(error);
}
};
const nextOnRejected = function(reason) {
let result;
try {
result = onRejected(reason);
promiseResolutionProcedure(chainPromise, result);
} catch (error) {
chainPromise._reject(error);
}
};
switch (this._state) {
case FULFILLED: {
nextTick(() => {
nextOnFulfilled(this._value);
});
break;
}
case REJECTED: {
nextTick(() => {
nextOnRejected(this._reason);
});
break;
}
case PENDING: {
this._resolveFnQueues.push(nextOnFulfilled);
this._rejectFnQueuse.push(nextOnRejected);
}
}
return chainPromise;
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
toString() {
switch (this._state) {
case PENDING:
return "Promise { <pending> }";
case FULFILLED:
return "Promise { " + this._value + " }";
case REJECTED:
return "Promise { <rejected> " + this._reason + " }";
}
}
static resolve(value) {
return new MyPromise(resolve => resolve(value));
}
static reject() {
return new MyPromise((resolve, reject) => reject(value));
}
}
复制代码
async 本质就是将 Generator 函数和自动执行器,包装在一个函数里浏览器
阮一峰大大的文章讲的炒鸡清楚了。这里的内容也来自于那篇文章,本人也就温习实现一下.async
// async 的写法
async function fn(args){
// ...
}
// 等同于
function fn(args){
return spawn(function*() {
// ...
});
}
//spawn 的实现方式
function spawn(genF) {
return new Promise(function(resolve, reject) {
var gen = genF();
step(function() { return gen.next(undefined); });
function step(nextF) {
try {
var next = nextF();
} catch(e) {
return reject(e);
}
if(next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() { return gen.next(v); });
}, function(e) {
step(function() { return gen.throw(e); });
});
}
});
}
复制代码