catch 不会中断 promise ,可以继续向后传。

  1. function resolvePromise(promise2, x, resolve, reject) {
  2. if (promise2 === x) {
  3. return reject(new TypeError('循环引用'));
  4. }
  5. if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
  6. let called; // 防止被多次调用 resolve reject
  7. try { // 防止取then是出现异常 Object.defineProperty
  8. let then = x.then; // 取x的then方法 {then:{}}
  9. if (typeof then === 'function') { // 如果then是函数我就认为 x 是个promise
  10. // call 第一个参数是 this ,后面的是成功的回调和失败的回调
  11. then.call(x, y => { // 如果y是promise就继续递归解析promise
  12. if (called) return;
  13. called = true;
  14. /*
  15. p.then(()=>{
  16. return new Promise((resolve,reject)=>{
  17. resolve(new Promise())
  18. })
  19. })
  20. */
  21. resolvePromise(promise2, y, resolve, reject);
  22. }, r => { // 只要失败了就失败了
  23. if (called) return;
  24. called = true;
  25. reject(r);
  26. });
  27. } else { // then是一个普通对象,就直接成功即可1
  28. resolve(x);
  29. }
  30. } catch (e) {
  31. if (called) return;
  32. called = true;
  33. reject(e);
  34. }
  35. } else { // x = 123
  36. resolve(x); // x就是一个普通值
  37. }
  38. }
  39. class Promise {
  40. constructor(executor) {
  41. this.status = 'pending';
  42. this.value = undefined;
  43. this.reason = undefined;
  44. this.onResolvedCallbacks = [];
  45. this.onRejectedCallbacks = [];
  46. let resolve, reject
  47. resolve = (data) => {
  48. // 如果 resolve 里面是一个 Promise ,注册then里面的方法。
  49. if(value instanceof Promise){
  50. return value.then(resolve,reject)
  51. }
  52. if (this.status === 'pending') {
  53. this.value = data;
  54. this.status = 'resolved';
  55. this.onResolvedCallbacks.forEach(fn => fn());
  56. }
  57. }
  58. reject = (reason) => {
  59. if (this.status === 'pending') {
  60. this.reason = reason;
  61. this.status = 'rejected';
  62. this.onRejectedCallbacks.forEach(fn => fn());
  63. }
  64. }
  65. try {
  66. executor(resolve, reject);
  67. } catch (e) {
  68. reject(e);
  69. }
  70. }
  71. then(onFulFilled, onRejected) {
  72. // 值的穿透 p.then().then().then(data=>{console.log(data)})
  73. onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : y => y;
  74. onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
  75. let promise2;
  76. if (this.status === 'resolved') {
  77. promise2 = new Promise((resolve, reject) => {
  78. setTimeout(() => {
  79. try {
  80. let x = onFulFilled(this.value);
  81. resolvePromise(promise2, x, resolve, reject);
  82. } catch (e) {
  83. reject(e);
  84. }
  85. }, 0);
  86. });
  87. }
  88. if (this.status === 'rejected') {
  89. promise2 = new Promise((resolve, reject) => {
  90. setTimeout(() => {
  91. try {
  92. let x = onRejected(this.reason);
  93. resolvePromise(promise2, x, resolve, reject)
  94. } catch (e) {
  95. reject(e);
  96. }
  97. }, 0);
  98. });
  99. }
  100. if (this.status === 'pending') {
  101. promise2 = new Promise((resolve, reject) => {
  102. this.onResolvedCallbacks.push(() => {
  103. setTimeout(() => {
  104. try {
  105. let x = onFulFilled(this.value);
  106. resolvePromise(promise2, x, resolve, reject)
  107. } catch (e) {
  108. reject(e);
  109. }
  110. }, 0)
  111. });
  112. // 存放失败的回调
  113. this.onRejectedCallbacks.push(() => {
  114. setTimeout(() => {
  115. try {
  116. let x = onRejected(this.reason);
  117. resolvePromise(promise2, x, resolve, reject);
  118. } catch (e) {
  119. reject(e);
  120. }
  121. }, 0);
  122. });
  123. })
  124. }
  125. return promise2; // 调用then后返回一个新的promise
  126. }
  127. // catch接收的参数 只用错误
  128. catch(onRejected) {
  129. // catch就是then的没有成功的简写
  130. return this.then(null, onRejected);
  131. }
  132. }
  133. Promise.resolve = function (val) {
  134. return new Promise((resolve, reject) => resolve(val))
  135. }
  136. Promise.reject = function (reason) {
  137. return new Promise((resolve, reject) => reject(reason));
  138. }
  139. // 有一个失败就失败,有一个成功就成功
  140. Promise.race = function (promises) {
  141. return new Promise((resolve, reject) => {
  142. for (let i = 0; i < promises.length; i++) {
  143. // 判断下是否是 promise
  144. let current = promises[i]
  145. if((typeof current === 'object' && current !== null) || typeof current === 'function'){
  146. if(typeof current.then === 'function'){
  147. current.then(resolve,reject)
  148. }else{
  149. resolve(current);
  150. }
  151. }else{
  152. resolve(current);
  153. }
  154. }
  155. });
  156. }
  157. // 有一个失败直接失败,全部成功才成功
  158. Promise.all = function (promises) {
  159. return new Promise((resolve,reject)=>{
  160. let result = [];
  161. let i = 0; // i的目的是为了保证获取全部成功,来设置的索引
  162. function processData(index,data) {
  163. result[index] = data;
  164. i++;
  165. if (i === promises.length){
  166. resolve(result);
  167. }
  168. }
  169. for(let i = 0;i<promises.length;i++){
  170. // 判断下是否是 promise
  171. let current = promises[i]
  172. if((typeof current === 'object' && current !== null) || typeof current === 'function'){
  173. if(typeof current.then === 'function'){
  174. current.then(data=>{
  175. processData(i,data);
  176. },reject)
  177. }else{
  178. processData(i,current);
  179. }
  180. }else{
  181. processData(i,current);
  182. }
  183. }
  184. })
  185. }
  186. // 使用 promise A+ 测试
  187. // 延迟对象 deferred
  188. Promise.deferred = Promise.defer = function () {
  189. let dfd = {};
  190. dfd.promise = new Promise((resolve, reject) => {
  191. dfd.resolve = resolve;
  192. dfd.reject = reject;
  193. })
  194. return dfd;
  195. }
  196. module.exports = Promise;

上面暴露的 Promise.deferred 延迟对象使用:

  1. function read(url){
  2. let dfd = Promise.defer()
  3. fs.readFile(url,'utf8',(err,data)=>{
  4. if(err) dfd.reject(err)
  5. dfd.resolve(data)
  6. })
  7. return dfd.promise
  8. }
  9. read('1.txt').then(data=>{
  10. console.log(data)
  11. })

看下面代码,输出什么?

  1. const p = Promise.resolve();
  2. (async () => {
  3. await p;
  4. console.log("after:await");
  5. })();
  6. p.then(() => {
  7. console.log("tick:a");
  8. }).then(() => {
  9. console.log("tick:b");
  10. });

在新版本的浏览器跟node 版本中都是下面的输出:

  1. tick:a
  2. tick:b
  3. after:await

那为什么 tick a 会比 after:await 快呢?我们把 async 函数转成 promise 就容易理解了:

  1. const p = Promise.resolve();
  2. (() => {
  3. const implicit_promise = new Promise(resolve => {
  4. const promise = new Promise(res => res(p));
  5. promise.then(() => {
  6. console.log("after:await");
  7. resolve();
  8. });
  9. });
  10. return implicit_promise;
  11. })();
  12. p.then(() => {
  13. console.log("tick:a");
  14. }).then(() => {
  15. console.log("tick:b");
  16. });

上面的输出就是: tick:a tick:b after:await

那如果在 p 后面再加一个 then 呢?如下:

  1. const p = Promise.resolve()
  2. ;(() => {
  3. const implicit_promise = new Promise(resolve => {
  4. const promise = new Promise(res => res(p))
  5. promise.then(() => {
  6. console.log('after:await')
  7. resolve()
  8. })
  9. })
  10. return implicit_promise
  11. })()
  12. p.then(() => {
  13. console.log('tick:a')
  14. }).then(() => {
  15. console.log('tick:b')
  16. }).then(()=>{
  17. console.log('tick:c')
  18. })

上面的输出就是: tick:a tick:b after:await tick:c

分析:
new Promise(res => res(p)) 中 res(p) 这个 p = Promise.resolve() 是立即成功的,就会立马调用 p.then 的 tick:a ,由于这个 then 没有返回值,立即往微任务队列放入 tick:b ,相当于 x = p.then(()=>{console.log(‘tick:a’)});x.then(()=>{console.log(“tick:b”)});在调用了 tick:a 这个 then 后, promise 这个 Promise 就执行成功了,所以 after:await 这个 promise.then 会跟在 tick:b 之后放入微任务队列。最后才是 tick:c。

推荐阅读:

v8是怎么实现更快的 await ?深入理解 await 的运行机制