Promise(3)-周边方法实现

468 阅读1分钟

本文我们来实现Promise的resolve、reject、all、race、finally方法。

resolve

创建一个成功的promise

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

reject

创建一个失败的promise

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

all

  • 参数是一个数组,数组内是一个一个的promise

  • 最终返回一个新的promise

这些数组内的promise会并行执行,当所有的promise都变为fulfilled,最终返回的这个新的promise的状态才会变为fulfilled, 只要有一个promise状态变为rejected,那么最终返回的这个新的pomise的状态就是rejected

Promise.all = function(promises) {
  return new Promise((resolve, reject) => {
    let result = [];
    let len = promises.length;
    if(len === 0) {
      resolve(result);
      return;
    }
    const handleData = (data, index) => {
      result[index] = data;
      // 最后一个 promise 执行完
      if(index == len - 1) resolve(result);
    }
    for(let i = 0; i < len; i++) {
      // 为什么不直接 promise[i].then, 因为promise[i]可能不是一个promise
      Promise.resolve(promise[i]).then(data => {
        handleData(data, i);
      }).catch(err => {
        reject(err);
      })
    }
  })
}

race

race和all的唯一区别就是只要数组中任何一个promise率先改变状态,最终返回的新的promise的状态就跟着改变。

知道了all方法的实现原理,race就简单了。

Promise.race = function(promises) {
  return new Promise((resolve, reject) => {
    let len = promises.length;
    if(len === 0) return;
    for(let i = 0; i < len; i++) {
      Promise.resolve(promise[i]).then(data => {
        resolve(data);
        return;
      }).catch(err => {
        reject(err);
        return;
      })
    }
  })
}

finally

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

Promise.prototype.finally = function(callback) {
  this.then(value => {
    return Promise.resolve(callback()).then(() => {
      return value;
    });
  }, error => {
    return Promise.resolve(callback()).then(() => {
      throw error;
    });
  });
}

finally也是返回一个新的promise实例,内部还是会调用外层promise.then方法获取状态,然后把callback()执行后的结果封装成一个promise把外层promise的结果透传下去。