Promise 规范有很多,如 Promise/A , Promise/B ,Promise/D 以及 Promise/A 的 升级版 Promise/A+ 。最终 ES6 中采用了 Promise/A+ 规范。(Promise/A+规范中文翻译)
const PENDING = 'pending'; // 等待态
const FULFILLED = 'fulfilled'; // 执行态
const REJECTED = 'rejected'; // 拒绝态
class MyPromise {
constructor(fn) {
this.value = null;
this.error = null;
this.status = PENDING;
// 当promise为pending状态时,存储回调函数
// 用于实现异步串行
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// callback(this.value);
this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
}
};
const reject = (error) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.error = error;
this.onRejectedCallbacks.forEach((callback) => callback(this.error));
}
};
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
// onFulfilled 当 promise 执行结束后其必须被调用,其第一个参数为 promise 的终值
// onRejected 当 promise 被拒绝执行后其必须被调用,其第一个参数为 promise 的据因
then(onFulfilled, onRejected) {
let bridgePromise;
// 默认给个函数
onFulfilled =
typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
onRejected =
typeof onRejected === 'function'
? onRejected
: (error) => {
throw error;
};
if (this.status === FULFILLED) {
bridgePromise = new MyPromise((resolve, reject) => {
// A+规范,异步执行
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
return bridgePromise;
}
if (this.status === REJECTED) {
bridgePromise = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
const x = onRejected(this.error);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
return bridgePromise;
}
if (this.status === PENDING) {
bridgePromise = new MyPromise((resolve, reject) => {
// 处理异步resolve
// 回调函数放入 onFulfilledCallbacks 中
// 回调函数负责执行 onFulfilled 和 更新 bridgePromise 的状态
// promise.then().then()
// 当前 promise 的 onFulfilledCallbacks 里的回调函数
// 负责执行.then里面的回调函数和更新.then返回的bridgePromise状态
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
// 执行回调
const x = onFulfilled(value);
// resolve(x)下去
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push((error) => {
console.log(error);
setTimeout(() => {
try {
// onRejected如果不抛出异常,则为执行态
// 比如catch回调中如果不抛出异常,那么这个catch返回的就是执行态
const x = onRejected(error);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
console.log(e);
reject(e);
}
});
});
});
return bridgePromise;
}
}
catch(onRejected) {
return this.then(null, onRejected);
}
}
function resolvePromise(bridgePromise, x, resolve, reject) {
// 避免循环引用
if (bridgePromise === x) {
return reject(new TypeError('Circular reference'));
}
// 避免重复调用
/*
Promise.resolve().then(() => {
return new Promise((resolve, reject) => {
resolve();
reject(); // 这种情况就要用called来避免重复调用
})
})
*/
let called = false;
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
// 在取 x.then 情况下,有可能出现异常
// 需要 try catch 包裹
try {
// 具有 then 方法的对象或者函数
// 比如是个Promise实例
let then = x.then;
if (typeof then === 'function') {
// 如果 then 是一个函数
// 以 x 为 this 调用 then 函数
then.call(
x,
(y) => {
if (called) {
return;
}
called = true;
resolvePromise(bridgePromise, y, resolve, reject);
},
(r) => {
if (called) {
return;
}
called = true;
reject(r);
}
);
} else {
// 如果 then 不是函数,以 x 为参数resolve promise
// .then(res => 123).then(x => console.log(x)) 透传
resolve(x);
}
} catch (error) {
// 如果出错了也是不能继续调用resolve和reject函数
if (called) {
return;
}
called = true;
reject(error);
}
} else {
// 如果 x 不为对象或者函数,以 x 为参数执行 promise
// 设置 this.value
resolve(x);
}
}
MyPromise.resolve = function (value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise((resolve, reject) => {
if (value && value.then && typeof value.then === 'function') {
setTimeout(() => {
value.then(resolve, reject);
});
} else {
resolve(value);
}
});
};
MyPromise.reject = function (error) {
return new MyPromise((resolve, reject) => {
reject(error);
});
};
MyPromise.all = function (promises) {
return new MyPromise((resolve, reject) => {
let result = [];
let count = 0; // 做个标记进行统计
for (let i = 0; i < promises.length; i++) {
promises[i].then(
function (data) {
result[i] = data;
count++;
// 在放到count为promises.length的promise的onFulfilled回调中进行resolve
// 因为count如果为promises.length,则说明所有的promise都fulfilled了
if (count === promises.length) {
resolve(result);
}
},
function (error) {
reject(error);
}
);
}
});
};
MyPromise.race = function (promises) {
return new MyPromise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(
// 有个promise执行态了,就直接resolve
(data) => {
resolve(data);
},
(error) => reject(error)
);
}
});
};
MyPromise.promisify = function (fn) {
return function (...args) {
return new MyPromise((resolve, reject) => {
fn.apply(
null,
args.concat((err) => {
err ? reject(err) : resolve(args[1]);
})
);
});
};
};
MyPromise.deferred = function () {
let defer = {};
defer.promise = new MyPromise((resolve, reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
};
module.exports = MyPromise;
简单版
function MyPromise(fn) {
this.cbs = [];
this.value = null;
const resolve = (value) => {
setTimeout(() => {
this.value = value;
this.cbs.forEach((cb) => cb(value));
});
}
fn(resolve);
}
MyPromise.prototype.then = function (onResolved) {
return new MyPromise((resolve) => {
this.cbs.push(() => {
const res = onResolved(this.value);
if (res instanceof MyPromise) {
res.then(resolve);
} else {
resolve(res);
}
});
});
};
https://zhuanlan.zhihu.com/p/58428287?utm_source=wechat_timeline