手把手实现Promise

1,333 阅读12分钟

手把手实现Promise

基本结构

  • Promise 构造函数传入一个函数new Promise((resolve, reject) => resolve(1))
  • 函数中有两个参数为resolvereject的函数
  • Promise 返回一个含有then方法的实例 p.then()
  • then方法可以传入两个函数分别是resolved来获取Promise成功状态的值,和rejected来获取Promise失败的值.

基本结构代码如下:

function Promise(executor) {

  const resolve = () => {

  }

  const reject = () => {
    
  }
  // 执行传入的函数参数
  executor(resolve, reject);
}
// 增加then方法
Promise.prototype.then = function (onResolved, onRejected) {

}

增加状态和返回值

基本结构搭建好后,我们知道在使用Promise中不管是resolve还是reject最终都只会出现一种状态和对应的返回结果值。例如下面例子:

// resolve值 只会执行resolve
new Promise(resolve, reject => {
  resolve('success');
});
// reject值 只会执行reject
new Promise(resolve, reject => {
  reject('reject');
});
// reject值 只会执行resolve()
let p = new Promise((resolve, reject) => {
  resolve(1);
  reject(2);
});
p.then(data => {
  console.log(data); //1
}, error => {
  console.log(error);
})

接着继续完善Promise:

  • 增加一个变量status记录当前实例状态,三种状态pending、fulfilled、rejected,默认pending
  • 增加一个变量储存resolve
  • 增加一个变量储存reject
function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值

  const resolve = value => {
    this.value = value;
  }

  const reject = reason => {
    this.reason = reason;
  }

  executor(resolve, reject);
}
Promise.prototype.then = function (onResolved, onRejected) {
  onResolved(this.value);
  onRejected(this.reason);
}

这里then放在原型上是因为实例可以直接共享一份原型,而不是每次都需要新建,这样减少内存使用

状态唯一性

上面代码在then实现中会执行resolvereject两个,会有两个返回值,在真实的Promise中只会出现一种状态,接下来需要做的是状态的处理:

// 增加状态处理的逻辑
function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值

  const resolve = value => {
    // 只有进入等待状态 才能进入解决状态
    if (this.status === 'pending') {
      this.value = value;
      this.status = 'fulfilled';
    }
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态
    if (this.status === 'pending') {
      this.reason = reason;
      this.status = 'rejected';
    }
  }

  executor(resolve, reject);
}
Promise.prototype.then = function (onResolved, onRejected) {
  if (this.status === 'fulfilled') {
    onResolved(this.value);
  }
  if (this.status === 'rejected') {
    onRejected(this.reason);
  }
}

上面Promise已经是能正常运行起来了,能正常的输出结果,算是一个初级版本了。
但是如果我们的Promise执行下面例子:

let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('res');
  }, 3000)
});
p.then(res => console.log(res)); // 没有输出

并没有输出结果,因为我们的Promise代码是同步的,而例子中使用异步setTimeout,而then方法的实现不会等待异步的fulfilled状态,而是在pending状态的时候直接返回了空。

增加异步的支持

解决上面例子的中异步问题,我们需要在then中保存resolvereject的回调函数,然后在状态变化时候来调用,调整如下:

function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值
  this.onResolvedFunc = Function.prototype; // 使用Function原型作为默认函数值
  this.onRejectedFunc = Function.prototype;

  const resolve = value => {
    // 只有进入等待状态 才能进入解决状态 并触发回调
    if (this.status === 'pending') {
      this.value = value;
      this.status = 'fulfilled';
      this.onResolvedFunc(this.value);
    }
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态 并触发回调
    if (this.status === 'pending') {
      this.reason = reason;
      this.status = 'rejected';
      this.onRejectedFunc(this.reason);
    }
  }

  executor(resolve, reject);
}
Promise.prototype.then = function (onResolved, onRejected) {
  if (this.status === 'fulfilled') {
    onResolved(this.value);
  }
  if (this.status === 'rejected') {
    onRejected(this.reason);
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    this.onResolvedFunc = onResolved;
    this.onRejectedFunc = onRejected;
  }
}

现在我们的Promise是支持异步了,但是现在又面临新的问题,我们知道Promisethen函数中的代码是异步的,请看下面例子:

let p = new Promise((resolve, reject) => {
  resolve('2');
});
p.then(res => console.log(res));
console.log('1');

官方Promise上面例子是先输出1再输出2,我们的版本是21
我们需要如何实现then中代码异步化,很简单,放在setTimeout中执行就可以了,调整后的Promise代码:

function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值
  this.onResolvedFunc = Function.prototype; // 使用Function原型作为默认函数
  this.onRejectedFunc = Function.prototype;

  const resolve = value => {
    // 只有进入等待状态 才能进入解决状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.value = value;
        this.status = 'fulfilled';
        this.onResolvedFunc(this.value);
      }
    });
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.reason = reason;
        this.status = 'rejected';
        this.onRejectedFunc(this.reason);
      }
    });
  }

  executor(resolve, reject);
}
Promise.prototype.then = function (onResolved, onRejected) {
  if (this.status === 'fulfilled') {
    onResolved(this.value);
  }
  if (this.status === 'rejected') {
    onRejected(this.reason);
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    this.onResolvedFunc = onResolved;
    this.onRejectedFunc = onRejected;
  }
}

处理多个then的问题

在正常的Promise中会出现连续调用多个then,例如:

let p = new Promise((resolve, reject) => {
  resolve(1);
});
p.then(res => console.log("res1:", res)); //res1: 1
p.then(res => console.log("res2:", res)); //res2: 1

而我们的Promise只会输出后面的结果,原因是第二次的then覆盖了之前的then,所以最终只会执行一个,我们需要改成数组的形式存放reject和resolve即可,调整如下:

function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值
  this.onResolvedArray = []; //数组存放
  this.onRejectedArray = [];

  const resolve = value => {
    // 只有进入等待状态 才能进入解决状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.value = value;
        this.status = 'fulfilled';
        // 调用所有的then resolve
        this.onResolvedArray.forEach(fun => fun(this.value));
      }
    });
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.reason = reason;
        this.status = 'rejected';
        // 调用所有的then reject
        this.onRejectedArray.forEach(fun => fun(this.reason));
      }
    });
  }

  executor(resolve, reject);
}
Promise.prototype.then = function (onResolved, onRejected) {
  if (this.status === 'fulfilled') {
    onResolved(this.value);
  }
  if (this.status === 'rejected') {
    onRejected(this.reason);
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    // 保存resolve reject
    this.onResolvedArray.push(onResolved);
    this.onRejectedArray.push(onRejected);
  }
}

现在我们的Promise可以执行多个then了。

增加链式调用支持

看一个例子:

const p = new Promise((resolve, reject) => {
  resolve(1);
});

//1.支持 then后面接着调用then 
p.then(res => {
  console.log(res);
})
.then(res => {
  console.log(222);
});
// 依次输出 1 2

思路:

  • 要实现then的链式调用必须在then函数中返回一个Promise才能继续支持调用then
  • 也就是说then中的resolvereject函数中中必须返回Promise
  • 我们将status三种状态的执行结果保存通过一个新的Promise返回

调整后:

Promise.prototype.then = function (onResolved, onRejected) {
  if (this.status === 'fulfilled') {
    // 返回一个新的Promise实例
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 保存resolve执行的结果
          let result = onResolved(this.value);
          resolve(result);
        } catch (e) { 
          reject(e);
        }
      });
    });
  }
  if (this.status === 'rejected') {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          let result = onRejected(this.reason);
          resolve(result);
        } catch (e) {
          reject(e);
        }
      })
    })
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    // 保存resolve reject
    return new Promise((resolve, reject) => {
      this.onResolvedArray.push(() => {
        try {
          let result = onResolved(this.value);
          resolve(result);
        } catch (e) {
          reject(e)
        }
      });
      this.onRejectedArray.push(() => {
        try {
          let result = onRejected(this.reason);
          resolve(result);
        } catch (e) {
          reject(e)
        }
      });
    });
  }
}

三种状态下的resolve、reject函数都需要通过新的Promise包装一层在返回结果 这样确实可以支持then链式调用了,但是有一种情况,如下例子:

let p4 = new Promise((resolve, reject) => {
  resolve(1)
});

p4.then(res => {
  console.log(res);
  return new Promise((resolve, reject) => {
    resolve(2);
  });
})
.then(res => {
  console.log(res)
})
.then(res => {
  console.log(4)
})

结果
我们在第一次then函数中返回一个 新的 Promise,接着继续执行了两次then,实际输出是有问题的,没有按预期的输出结果1 2 4,少输出了2
我们目前的Promise中then只是处理了普通resolve reject返回值,如果遇到了Promise也被当作正常值处理就拿不到值,所以我们需要对Promise做处理。
新增一个函数resolvePromise处理Promise 和 普通值,如下:

// 新增一个函数处理Promise 和 普通值
const resolvePromise = (promise, result, resolve, reject) => {
  // 当promise 和 result相等
  if (promise === result) {
    reject(new TypeError('error due to circular reference'));
  }

  let consumed = false,// 是否已经执行 
    thenable = null; // 保存then函数
  
  // 如果result是Promise 实例
  if (result instanceof Promise) {
    if (result.status === 'pending') {
      result.then(function (data) {
        // 继续递归调用
        resolvePromise(promise, data, resolve, reject);
      }, reject)
    } else {
      result.then(resolve, reject);
    }

    return;
  }

  const isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null);

  // 如果result 疑似 Promise
  if (isComplexResult(result)) {
    try {
      thenable = result.then;
      // 如果result有then方法
      if (typeof thenable === 'function') {
        thenable.call(result, function (data) {
          if (consumed) {
            return;
          }
          consumed = true;
          // 递归
          return resolvePromise(promise, data, resolve, reject);
        }, function(error) {
          if (consumed) return;

          consumed = true;
          return reject(error);
        })
      }

    } catch (e) {
      if (consumed) return;

      consumed = true;
      return reject(e);
    }
  } else {
    resolve(result);
  }
}

promise: 需要返回的Promise
result: reject 或 resolve 执行的结果
resolve: 需要返回的Promise 的 resolve
reject: 需要返回的Promise 的 reject
所谓疑似就是result是function或者对象并且有then方法,我们也当做Promise来处理
上面代码实现 多次使用递归和 pending状态处理,需要反复理解才能想通 [dog]

接着在thenresult返回值使用resolvePromise处理:

Promise.prototype.then = function (onResolved, onRejected) {
  // 保存promise
  let promise = null;

  if (this.status === 'fulfilled') {
    // 返回一个新的Promise实例
    return promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 保存resolve执行的结果
          let result = onResolved(this.value);
          resolvePromise(promise, result, resolve, reject);
        } catch (e) { 
          reject(e);
        }
      });
    });
  }
  if (this.status === 'rejected') {
    return promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise, result, resolve, reject);
        } catch (e) {
          reject(e);
        }
      })
    })
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    // 保存resolve reject
    return promise = new Promise((resolve, reject) => {
      this.onResolvedArray.push(() => {
        try {
          let result = onResolved(this.value);
          resolvePromise(promise, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
      this.onRejectedArray.push(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
    });
  }
}

完整代码:

function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值
  this.onResolvedArray = []; //数组存放
  this.onRejectedArray = [];

  const resolve = value => {
    if (value instanceof Promise) {
      return value.then(resolve, reject);
    }
    // 只有进入等待状态 才能进入解决状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.value = value;
        this.status = 'fulfilled';
        // 调用所有的then resolve
        this.onResolvedArray.forEach(fun => fun(value));
      }
    });
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.reason = reason;
        this.status = 'rejected';
        // 调用所有的then reject
        this.onRejectedArray.forEach(fun => fun(reason));
      }
    });
  }

  executor(resolve, reject);
}

const resolvePromise = (promise2, result, resolve, reject) => {
  // 当promise 和 result相等 直接返回错误
  if (result === promise2) {
    reject(new TypeError('error due to circular reference'));
  }

  let consumed = false; //是否执行了
  let thenable; // 保存then函数
  
  // 如果result是Promise 实例
  if (result instanceof Promise) {
    if (result.status === 'pending') {
      result.then(function (data) {
        // 继续递归调用
        resolvePromise(promise2, data, resolve, reject);
      }, reject);
    } else {
      result.then(resolve, reject);
    }
    return;
  }

  let isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null);

  // 如果result 疑似 Promise
  if (isComplexResult(result)) {
    try {
      thenable = result.then;
      // 如果result有then方法
      if (typeof thenable === 'function') {
        thenable.call(result, function (data) {
          if (consumed) {
            return;
          }
          consumed = true;
          // 递归
          return resolvePromise(promise2, data, resolve, reject);
        }, function(error) {
          if (consumed) return;

          consumed = true;
          return reject(error);
        })
      } else {
        resolve(result);
      }

    } catch (e) {
      if (consumed) return;

      consumed = true;
      return reject(e);
    }
  } else {
    resolve(result);
  }
}

Promise.prototype.then = function (onResolved, onRejected) {
  onResolved = typeof onResolved === 'function' ? onResolved : data => data;
  onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };
  // 保存promise
  let promise2 = null;

  if (this.status === 'fulfilled') {
    // 返回一个新的Promise实例
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 保存resolve执行的结果
          let result = onResolved(this.value);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) { 
          reject(e);
        }
      });
    });
  }
  if (this.status === 'rejected') {
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e);
        }
      })
    })
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    // 保存resolve reject
    return promise2 = new Promise((resolve, reject) => {
      this.onResolvedArray.push(() => {
        try {
          let result = onResolved(this.value);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
      this.onRejectedArray.push(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
    });
  }
}

上面代码增加一些参数容错处理onResolved、onRejected 设置默认参数,resolve函数,value如果是Promise直接调用

onResolved = typeof onResolved === 'function' ? onResolved : data => data;
onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };

const resolve = value => {
  if (value instanceof Promise) {
    return value.then(resolve, reject);
  }
}

Promise 穿透现象

什么是穿透现象,看下面例子:

let p = new Promise((resolve, reject) => {
  resolve(1);
});
p.then(null)
  .then(() => {
    console.log(2)
  });

// 2

简而言之如果第一个then函数是null,会跳过当前then继续往下执行 我们实现的Promise中已经支持穿透现象,当参数为nullonResolved、onRejected设置默认函数即可。

Promise.prototype.then = function (onResolved, onRejected) {
  onResolved = typeof onResolved === 'function' ? onResolved : data => data;
  onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };

  //...
}

静态方法的支持

  • Promise.prototype.catch
  • Promise.resolve
  • Promise.reject
  • Promise.all
  • Promise.race

Promise.prototype.catch

// demo
let promise1 = new Promise((res, rej) => {
  rej('error');
});
promise1.then(data => {
 console.log(data)
}).catch(error => {
 console.log(error); // error
});

// 实现
Promise.prototype.catch = function (catchFunc) {
  return this.then(null, catchFunc);
}

使用then的第二个参数来捕获来实现

Promise.resolve 和 Promise.reject

使用场景:

Promise.resolve('res').then(data => {
 console.log(data);
})
console.log(1);

Promise.resolve返回新的Promise实例和实例的resolve函数执行后的结果,reject同理,实现代码:

Promise.resolve = function (value) {
  return new Promise((resolve, reject) => {
    resolve(value);
  });
}
Promise.reject = function (value) {
  return new Promise((resolve, reject) => {
    reject(value);
  });
}

Promise.all

Promise.all返回一个Promise,接受一个Promise数组, 当所有Promiseresolve则返回resolve,有一个失败返回reject.
看下例子:

let p1 = new Promise((resolve, reject) => {
  resolve(1);
});
let p2 = new Promise((resolve, reject) => {
  resolve(2);
});

Promise.all([p1, p2]).then(res => {
  console.log(res);
});

执行结果输出:[1, 2].
实现思路:

  • 遍历执行所有的Promise
  • 保存每一个Promiseresolve执行结果
  • 执行完成后返回执行结果
  • 如果遍历的时候有一个出现reject则直接返回reject

实现代码:

Promise.all = function (promiseArray) {
  // 非数组报错
  if (!Array.isArray(promiseArray)) {
    throw new TypeError('arguments should be an array');
  }
  return new Promise((resolve, reject) => {
    try {
      let resultArray = [];
      const length = promiseArray.length;
      for (let i=0; i<length; i++) {
        // 执行Promise.then
        promiseArray[i].then(data => {
          // 保存结果
          resultArray.push(data);
          // 完成所有promise resolve结果
          if (resultArray.length === length) {
            resolve(resultArray);
          }
          // 其中有一个出现reject 则返回reject
        }, reject);
      }
    } catch(e) {
      // 出现异常直接reject
      reject(e);
    }
  });
}

Promise.race

all不一样,all是所有Promise都resolve才resolve,而race是当有一个Promise为先完成resolve就resolve.这里是竞争关系,实现思路是直接执行所有的Promise即可,谁先完成就会先返回
实现代码:

Promise.race = function(promiseArray) {
 if (!Array.isArray(promiseArray)) {
    throw new TypeError('arguments should be an array');
 }
 return new Promise((resolve, reject) => {
   try {
     for (let i=0; i<promiseArray.length; i++) {
       promiseArray[i].then(resolve, reject);
     }
   } catch (e) {
     reject(e);
   }
 });
}

一些细节问题

完成Promise静态方法之后Promise所有的功能就已经完成了,还需要处理一些细节问题:
executor 使用try catch包裹

function Promise(executor) {
  // executor 使用try catch包裹
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

完整代码

function Promise(executor) {
  this.status = 'pending'; //状态默认为等待
  this.value = null; // resolve值
  this.reason = null; // reject值
  this.onResolvedArray = []; //数组存放
  this.onRejectedArray = [];

  const resolve = value => {
    if (value instanceof Promise) {
      return value.then(resolve, reject);
    }
    // 只有进入等待状态 才能进入解决状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.value = value;
        this.status = 'fulfilled';
        // 调用所有的then resolve
        this.onResolvedArray.forEach(fun => fun(value));
      }
    });
  }

  const reject = reason => {
    // 只有进入等待状态,才能进入拒绝状态 并触发回调
    setTimeout(() => {
      if (this.status === 'pending') {
        this.reason = reason;
        this.status = 'rejected';
        // 调用所有的then reject
        this.onRejectedArray.forEach(fun => fun(reason));
      }
    });
  }

  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

const resolvePromise = (promise2, result, resolve, reject) => {
  // 当promise 和 result相等 直接返回错误
  if (result === promise2) {
    reject(new TypeError('error due to circular reference'));
  }

  let consumed = false; //是否执行了
  let thenable; // 保存then函数
  
  // 如果result是Promise 实例
  if (result instanceof Promise) {
    if (result.status === 'pending') {
      result.then(function (data) {
        // 继续递归调用
        resolvePromise(promise2, data, resolve, reject);
      }, reject);
    } else {
      result.then(resolve, reject);
    }
    return;
  }

  let isComplexResult = target => (typeof target === 'function' || typeof target === 'object') && (target !== null);

  // 如果result 疑似 Promise
  if (isComplexResult(result)) {
    try {
      thenable = result.then;
      // 如果result有then方法
      if (typeof thenable === 'function') {
        thenable.call(result, function (data) {
          if (consumed) {
            return;
          }
          consumed = true;
          // 递归
          return resolvePromise(promise2, data, resolve, reject);
        }, function(error) {
          if (consumed) return;

          consumed = true;
          return reject(error);
        })
      } else {
        resolve(result);
      }

    } catch (e) {
      if (consumed) return;

      consumed = true;
      return reject(e);
    }
  } else {
    resolve(result);
  }
}

Promise.prototype.then = function (onResolved, onRejected) {
  onResolved = typeof onResolved === 'function' ? onResolved : data => data;
  onRejected = typeof onRejected === 'function' ? onRejected : error => { throw error };
  // 保存promise
  let promise2 = null;

  if (this.status === 'fulfilled') {
    // 返回一个新的Promise实例
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          // 保存resolve执行的结果
          let result = onResolved(this.value);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) { 
          reject(e);
        }
      });
    });
  }
  if (this.status === 'rejected') {
    return promise2 = new Promise((resolve, reject) => {
      setTimeout(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e);
        }
      })
    })
  }
  // 储存resolve, reject回调函数
  if (this.status === 'pending') {
    // 保存resolve reject
    return promise2 = new Promise((resolve, reject) => {
      this.onResolvedArray.push(() => {
        try {
          let result = onResolved(this.value);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
      this.onRejectedArray.push(() => {
        try {
          let result = onRejected(this.reason);
          resolvePromise(promise2, result, resolve, reject);
        } catch (e) {
          reject(e)
        }
      });
    });
  }
}
// catch
Promise.prototype.catch = function (catchFunc) {
  return this.then(null, catchFunc);
}

// resolve
Promise.resolve = function (value) {
  return new Promise((resolve, reject) => {
    resolve(value);
  });
}

//reject
Promise.reject = function (value) {
  return new Promise((resolve, reject) => {
    reject(value);
  });
}

//all
Promise.all = function (promiseArray) {
  // 非数组报错
  if (!Array.isArray(promiseArray)) {
    throw new TypeError('arguments should be an array');
  }
  return new Promise((resolve, reject) => {
    try {
      let resultArray = [];
      const length = promiseArray.length;
      for (let i=0; i<length; i++) {
        promiseArray[i].then(data => {
          resultArray.push(data);
          // 完成所有promise resolve结果
          if (resultArray.length === length) {
            resolve(resultArray);
          }
          // 其中有一个出现reject 则返回reject
        }, reject);
      }
    } catch(e) {
      // 出现异常直接reject
      reject(e);
    }
  });
}
//race
Promise.race = function(promiseArray) {
 if (!Array.isArray(promiseArray)) {
    throw new TypeError('arguments should be an array');
 }
 return new Promise((resolve, reject) => {
   try {
     for (let i=0; i<promiseArray.length; i++) {
       promiseArray[i].then(resolve, reject);
     }
   } catch (e) {
     reject(e);
   }
 });
}

总结

链式调用resolvePromise实现比较难理解,需要反复阅读体会。

引用

书籍:前端开发核心知识进阶:50 讲从夯实基础到突破瓶颈