Promise 规范有很多,如 Promise/A , Promise/B ,Promise/D 以及 Promise/A 的 升级版 Promise/A+ 。最终 ES6 中采用了 Promise/A+ 规范。(Promise/A+规范中文翻译

    1. const PENDING = 'pending'; // 等待态
    2. const FULFILLED = 'fulfilled'; // 执行态
    3. const REJECTED = 'rejected'; // 拒绝态
    4. class MyPromise {
    5. constructor(fn) {
    6. this.value = null;
    7. this.error = null;
    8. this.status = PENDING;
    9. // 当promise为pending状态时,存储回调函数
    10. // 用于实现异步串行
    11. this.onFulfilledCallbacks = [];
    12. this.onRejectedCallbacks = [];
    13. const resolve = (value) => {
    14. if (this.status === PENDING) {
    15. this.status = FULFILLED;
    16. this.value = value;
    17. // callback(this.value);
    18. this.onFulfilledCallbacks.forEach((callback) => callback(this.value));
    19. }
    20. };
    21. const reject = (error) => {
    22. if (this.status === PENDING) {
    23. this.status = REJECTED;
    24. this.error = error;
    25. this.onRejectedCallbacks.forEach((callback) => callback(this.error));
    26. }
    27. };
    28. try {
    29. fn(resolve, reject);
    30. } catch (error) {
    31. reject(error);
    32. }
    33. }
    34. // onFulfilled 当 promise 执行结束后其必须被调用,其第一个参数为 promise 的终值
    35. // onRejected 当 promise 被拒绝执行后其必须被调用,其第一个参数为 promise 的据因
    36. then(onFulfilled, onRejected) {
    37. let bridgePromise;
    38. // 默认给个函数
    39. onFulfilled =
    40. typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
    41. onRejected =
    42. typeof onRejected === 'function'
    43. ? onRejected
    44. : (error) => {
    45. throw error;
    46. };
    47. if (this.status === FULFILLED) {
    48. bridgePromise = new MyPromise((resolve, reject) => {
    49. // A+规范,异步执行
    50. setTimeout(() => {
    51. try {
    52. const x = onFulfilled(this.value);
    53. resolvePromise(bridgePromise, x, resolve, reject);
    54. } catch (e) {
    55. reject(e);
    56. }
    57. });
    58. });
    59. return bridgePromise;
    60. }
    61. if (this.status === REJECTED) {
    62. bridgePromise = new MyPromise((resolve, reject) => {
    63. setTimeout(() => {
    64. try {
    65. const x = onRejected(this.error);
    66. resolvePromise(bridgePromise, x, resolve, reject);
    67. } catch (e) {
    68. reject(e);
    69. }
    70. });
    71. });
    72. return bridgePromise;
    73. }
    74. if (this.status === PENDING) {
    75. bridgePromise = new MyPromise((resolve, reject) => {
    76. // 处理异步resolve
    77. // 回调函数放入 onFulfilledCallbacks 中
    78. // 回调函数负责执行 onFulfilled 和 更新 bridgePromise 的状态
    79. // promise.then().then()
    80. // 当前 promise 的 onFulfilledCallbacks 里的回调函数
    81. // 负责执行.then里面的回调函数和更新.then返回的bridgePromise状态
    82. this.onFulfilledCallbacks.push((value) => {
    83. setTimeout(() => {
    84. try {
    85. // 执行回调
    86. const x = onFulfilled(value);
    87. // resolve(x)下去
    88. resolvePromise(bridgePromise, x, resolve, reject);
    89. } catch (e) {
    90. reject(e);
    91. }
    92. });
    93. });
    94. this.onRejectedCallbacks.push((error) => {
    95. console.log(error);
    96. setTimeout(() => {
    97. try {
    98. // onRejected如果不抛出异常,则为执行态
    99. // 比如catch回调中如果不抛出异常,那么这个catch返回的就是执行态
    100. const x = onRejected(error);
    101. resolvePromise(bridgePromise, x, resolve, reject);
    102. } catch (e) {
    103. console.log(e);
    104. reject(e);
    105. }
    106. });
    107. });
    108. });
    109. return bridgePromise;
    110. }
    111. }
    112. catch(onRejected) {
    113. return this.then(null, onRejected);
    114. }
    115. }
    116. function resolvePromise(bridgePromise, x, resolve, reject) {
    117. // 避免循环引用
    118. if (bridgePromise === x) {
    119. return reject(new TypeError('Circular reference'));
    120. }
    121. // 避免重复调用
    122. /*
    123. Promise.resolve().then(() => {
    124. return new Promise((resolve, reject) => {
    125. resolve();
    126. reject(); // 这种情况就要用called来避免重复调用
    127. })
    128. })
    129. */
    130. let called = false;
    131. if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
    132. // 在取 x.then 情况下,有可能出现异常
    133. // 需要 try catch 包裹
    134. try {
    135. // 具有 then 方法的对象或者函数
    136. // 比如是个Promise实例
    137. let then = x.then;
    138. if (typeof then === 'function') {
    139. // 如果 then 是一个函数
    140. // 以 x 为 this 调用 then 函数
    141. then.call(
    142. x,
    143. (y) => {
    144. if (called) {
    145. return;
    146. }
    147. called = true;
    148. resolvePromise(bridgePromise, y, resolve, reject);
    149. },
    150. (r) => {
    151. if (called) {
    152. return;
    153. }
    154. called = true;
    155. reject(r);
    156. }
    157. );
    158. } else {
    159. // 如果 then 不是函数,以 x 为参数resolve promise
    160. // .then(res => 123).then(x => console.log(x)) 透传
    161. resolve(x);
    162. }
    163. } catch (error) {
    164. // 如果出错了也是不能继续调用resolve和reject函数
    165. if (called) {
    166. return;
    167. }
    168. called = true;
    169. reject(error);
    170. }
    171. } else {
    172. // 如果 x 不为对象或者函数,以 x 为参数执行 promise
    173. // 设置 this.value
    174. resolve(x);
    175. }
    176. }
    177. MyPromise.resolve = function (value) {
    178. if (value instanceof MyPromise) {
    179. return value;
    180. }
    181. return new MyPromise((resolve, reject) => {
    182. if (value && value.then && typeof value.then === 'function') {
    183. setTimeout(() => {
    184. value.then(resolve, reject);
    185. });
    186. } else {
    187. resolve(value);
    188. }
    189. });
    190. };
    191. MyPromise.reject = function (error) {
    192. return new MyPromise((resolve, reject) => {
    193. reject(error);
    194. });
    195. };
    196. MyPromise.all = function (promises) {
    197. return new MyPromise((resolve, reject) => {
    198. let result = [];
    199. let count = 0; // 做个标记进行统计
    200. for (let i = 0; i < promises.length; i++) {
    201. promises[i].then(
    202. function (data) {
    203. result[i] = data;
    204. count++;
    205. // 在放到count为promises.length的promise的onFulfilled回调中进行resolve
    206. // 因为count如果为promises.length,则说明所有的promise都fulfilled了
    207. if (count === promises.length) {
    208. resolve(result);
    209. }
    210. },
    211. function (error) {
    212. reject(error);
    213. }
    214. );
    215. }
    216. });
    217. };
    218. MyPromise.race = function (promises) {
    219. return new MyPromise((resolve, reject) => {
    220. for (let i = 0; i < promises.length; i++) {
    221. promises[i].then(
    222. // 有个promise执行态了,就直接resolve
    223. (data) => {
    224. resolve(data);
    225. },
    226. (error) => reject(error)
    227. );
    228. }
    229. });
    230. };
    231. MyPromise.promisify = function (fn) {
    232. return function (...args) {
    233. return new MyPromise((resolve, reject) => {
    234. fn.apply(
    235. null,
    236. args.concat((err) => {
    237. err ? reject(err) : resolve(args[1]);
    238. })
    239. );
    240. });
    241. };
    242. };
    243. MyPromise.deferred = function () {
    244. let defer = {};
    245. defer.promise = new MyPromise((resolve, reject) => {
    246. defer.resolve = resolve;
    247. defer.reject = reject;
    248. });
    249. return defer;
    250. };
    251. module.exports = MyPromise;

    简单版

    1. function MyPromise(fn) {
    2. this.cbs = [];
    3. this.value = null;
    4. const resolve = (value) => {
    5. setTimeout(() => {
    6. this.value = value;
    7. this.cbs.forEach((cb) => cb(value));
    8. });
    9. }
    10. fn(resolve);
    11. }
    12. MyPromise.prototype.then = function (onResolved) {
    13. return new MyPromise((resolve) => {
    14. this.cbs.push(() => {
    15. const res = onResolved(this.value);
    16. if (res instanceof MyPromise) {
    17. res.then(resolve);
    18. } else {
    19. resolve(res);
    20. }
    21. });
    22. });
    23. };

    https://zhuanlan.zhihu.com/p/58428287?utm_source=wechat_timeline