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.valueresolve(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
