目录:1、new Promise()2、.then()及链式调用3、.resolve()和.reject()4、.all()和.race()

在手撕Promise之前咱们得先理解一下Promise的个性。
首先Promise实质就是一个构造函数,能够通过它发明Promise对象实例来实现异步编程的需要。
本篇文章咱们须要实现的Promise个性如下:


1、new Promise((resolve,reject) => {})
作为一个构造函数,最先须要实现的是其根本的架构,咱们先实现最根本的性能:

1)status存储状态、value和error存储胜利/失败状态的值2)resolve和reject办法扭转状态3)then办法实现状态扭转后的回调
class MyPromise {  constructor(executor) {    this.status = 'pending';    this.value;   // 胜利状态的值    this.error;   // 失败状态的值    this.resolveCallbacks = [];    this.rejectedCallbacks = [];    let resolve = (res) => {    }    let reject = (err) => {    }    executor(resolve, reject)  }  then(onFulfilled, onRejected) {  }  catch() {  }}

补充resolve和reject还有then和catch的内容

1)then最根本的性能就是状态扭转后调用回调函数2)catch实质就是只有失败状态的.then
class MyPromise {  constructor(executor) {    this.status = 'pending';    this.value;   // 胜利状态的值    this.error;   // 失败状态的值    this.resolveCallbacks = [];    this.rejectedCallbacks = [];    let resolve = (res) => {      // 转变状态、执行回调      if (this.status === 'pending') {        this.status = 'resolved';        this.value = res;      }    }    let reject = (err) => {      // 转变状态、执行回调      if (this.status === 'pending') {        this.status = 'rejected';        this.error = err;      }    }    executor(resolve, reject)  }  then(onFulfilled, onRejected) {    // 实质就是若以后状态为resolved或rejected 执行对应的回调函数    if (this.status === 'resolved') {      onFulfilled(this.value);    }    if (this.status === 'rejected') {      onRejected(this.error)    }  }  catch(rejected) {    return this.then(null, rejected)  }}

这样咱们就能够调用构造函数实现最根本的性能

let pro1 = new MyPromise((resolve, reject) => {  resolve('胜利了');}).then(res => {  console.log(res);})console.log(pro1);  // 胜利了

2、.then()及链式调用
下面then的写法存在几个问题:
1)当状态扭转在异步函数中,此时执行.then无奈立刻执行回调,应该存储期待状态扭转一起执行
2).then中的回调应该放在异步函数中,所以须要加setTimeout
3).then 返回值必须为Promise对象,所以每次异步解决的后果设为x,还需依据x决定返回的promise2的状态和值

这里引入resolvePromise办法决定返回的promise2的状态和值。
初步改良如下:

MyPromise.then(onFulfilled, onRejected) {    // 实质就是若以后状态为resolved或rejected 执行对应的回调函数    let promise2;    promise2 = new MyPromise((resolve, reject) => {      if (this.status === 'resolved') {        setTimeout(() => {          let x = onFulfilled(this.value);          resolvePromise(promise2, x, resolve, reject);        })      }      if (this.status === 'rejected') {        setTimeout(() => {          let x = onRejected(this.error);          resolvePromise(promise2, x, resolve, reject);        })      }      if (this.status === 'pending') {        this.resolveCallbacks.push(() => {          setTimeout(() => {            let x = onFulfilled(this.value);            resolvePromise(promise2, x, resolve, reject);          })        });        this.rejectedCallbacks.push(() => {          setTimeout(() => {            let x = onRejected(this.error);            resolvePromise(promise2, x, resolve, reject);          })        });      }    })    return promise2;  }

函数resolvePromise的实现是Promise实现的外围,其外部蕴含几个重要的规定,简略概括:
1)若返回值x是数值,则返回fulfiiled状态的Promise,value为x
2)若返回值x是Promise对象,则持续递归调用
3)只有当返回值x为rejected状态的Promise对象,返回的才是失败状态的Promise

function resolvePromise(promise2, x, resolve, reject) {  // 循环援用报错  if (x === promise2) {    // reject 报错抛出    return reject(new TypeError('Chaining cycle detected for promise'));  }  // 锁,避免屡次调用  let called;  // x不是null 且x是对象或者函数  if (x != null && (typeof x === 'object' || typeof x === 'function')) {    try {      // A+ 规定,申明then = x的then办法      let then = x.then;      // 如果then是函数,就默认是promise了      if (typeof then === 'function') {        // 就让then执行 第一个参数是this   前面是胜利的回调 和 失败的回调        then.call(x, y => {          // 胜利和失败只能调用一个          if (called) return;          called = true;          // resolve的后果仍旧是promise 那就持续递归执行          resolvePromise(promise2, y, resolve, reject);        }, err => {          // 胜利和失败只能调用一个          if (called) return;          called = true;          reject(err);// 失败了就失败了        })      } else {        resolve(x); // 间接胜利即可      }    } catch (e) {      // 也属于失败      if (called) return;      called = true;      // 取then出错了那就不要在继续执行了      reject(e);    }  } else {    resolve(x);  }}

then实现的最初还需补充一些细节,比方传入的onFullfilled若不是函数,则疏忽onFullfilled间接返回value;还有之前的resolve和reject退出回调数组的调用

onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;onRejected = typeof onRejected === 'function' ? onRejected : error => error;

3、.resolve()和.reject()
Promise还能够间接调用resolve和reject办法,其本质就是new Promise而后扭转状态。

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

4、.all()和.race()
首先说说all()办法,其本质就是只有当参数里所有Promise对象都fulfilled才返回值,其有以下个性:
Promise.all([promise1,promise2,...])
1)仅在数组内所有promise对象都resolve,才resolve,且返回Promise对象,value是所有promise对象胜利的value
2)如果有一个Promise对象reject,则返回第一个reject的promise后果
3)参数的promises只要求是可迭代对象,如果传递的不是Promise对象,则间接返回原值即可。

MyPromise.all = (promises) => {  // promises是数组  if (!Array.isArray(promises)) {    throw ('必须是数组')  }  let res = []  return new MyPromise((resolve, reject) => {    for (let i = 0; i < promises.length; i++) {      if (promises[i].then) {        // 是promise对象则.then        promises[i].then(r => {          res.push(r);          if (res.length === promises.length) {            // 全副胜利            return resolve(res);          }        }, error => {          return reject(error);        })      } else {        // 不是promise对象则间接存value        res.push(promises[i]);        if (res.length === promises.length) {          // 全副胜利          return resolve(res);        }      }    }  })}

race()办法与all相同,是只返回参数所有Promise对象最早扭转状态的对象,其个性如下:
Promise.race(promises)
1)当数组中某一个Promise的状态变为fulfilled/rejected,则race返回那个Promise状态及value
2)间接把race的resolve注入到数组每个对象的回调中

MyPromise.race = (promises) => {  return new MyPromise((resolve, reject) => {    for (let i = 0; i < promises.length; i++) {      promises[i].then(resolve, reject);    }  })}

所有Promise的手撕就实现了。