深入Promise实现原理

97 阅读2分钟

background.png Promise是一种异步编程的解决方案,它可以避免回调地狱,使得异步操作更加简洁和易于维护。下面是Promise的源码实现原理:

  1. Promise构造函数

Promise构造函数接受一个executor函数作为参数,executor函数会立即执行,并传入两个参数resolve和reject。resolve函数用于将Promise状态从pending变为fulfilled,reject函数用于将Promise状态从pending变为rejected。

function Promise(executor) {
  var self = this;
  self.status = 'pending'; // Promise状态
  self.data = undefined; // Promise的值
  self.onResolvedCallback = []; // Promise resolve时的回调函数集合
  self.onRejectedCallback = []; // Promise reject时的回调函数集合

  function resolve(value) {
    if (self.status === 'pending') {
      self.status = 'fulfilled';
      self.data = value;
      for (var i = 0; i < self.onResolvedCallback.length; i++) {
        self.onResolvedCallback[i](value);
      }
    }
  }

  function reject(reason) {
    if (self.status === 'pending') {
      self.status = 'rejected';
      self.data = reason;
      for (var i = 0; i < self.onRejectedCallback.length; i++) {
        self.onRejectedCallback[i](reason);
      }
    }
  }

  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}
  1. Promise.prototype.then方法

Promise.prototype.then方法用于注册Promise状态变为fulfilled或rejected时的回调函数。它接受两个参数,onResolved和onRejected,分别表示Promise状态变为fulfilled或rejected时的回调函数。

Promise.prototype.then = function(onResolved, onRejected) {
  var self = this;
  var promise2;

  onResolved = typeof onResolved === 'function' ? onResolved : function(value) { return value; };
  onRejected = typeof onRejected === 'function' ? onRejected : function(reason) { throw reason; };

  if (self.status === 'fulfilled') {
    return promise2 = new Promise(function(resolve, reject) {
      try {
        var x = onResolved(self.data);
        if (x instanceof Promise) {
          x.then(resolve, reject);
        } else {
          resolve(x);
        }
      } catch (e) {
        reject(e);
      }
    });
  }

  if (self.status === 'rejected') {
    return promise2 = new Promise(function(resolve, reject) {
      try {
        var x = onRejected(self.data);
        if (x instanceof Promise) {
          x.then(resolve, reject);
        } else {
          resolve(x);
        }
      } catch (e) {
        reject(e);
      }
    });
  }

  if (self.status === 'pending') {
    return promise2 = new Promise(function(resolve, reject) {
      self.onResolvedCallback.push(function(value) {
        try {
          var x = onResolved(value);
          if (x instanceof Promise) {
            x.then(resolve, reject);
          } else {
            resolve(x);
          }
        } catch (e) {
          reject(e);
        }
      });

      self.onRejectedCallback.push(function(reason) {
        try {
          var x = onRejected(reason);
          if (x instanceof Promise) {
            x.then(resolve, reject);
          } else {
            resolve(x);
          }
        } catch (e) {
          reject(e);
        }
      });
    });
  }
};
  1. Promise.prototype.catch方法

Promise.prototype.catch方法用于注册Promise状态变为rejected时的回调函数。它接受一个参数onRejected,表示Promise状态变为rejected时的回调函数。

Promise.prototype.catch = function(onRejected) {
  return this.then(null, onRejected);
};
  1. Promise.resolve方法

Promise.resolve方法用于创建一个状态为fulfilled的Promise对象,它接受一个参数value,表示Promise的值。

Promise.resolve = function(value) {
  return new Promise(function(resolve, reject) {
    resolve(value);
  });
};
  1. Promise.reject方法

Promise.reject方法用于创建一个状态为rejected的Promise对象,它接受一个参数reason,表示Promise被拒绝的原因。

Promise.reject = function(reason) {
  return new Promise(function(resolve, reject) {
    reject(reason);
  });
};
  1. Promise.all方法

Promise.all方法用于将多个Promise对象包装成一个新的Promise对象,当所有Promise对象都变为fulfilled时,新的Promise对象的状态才变为fulfilled,它的值是所有Promise对象的值组成的数组;当有一个Promise对象变为rejected时,新的Promise对象的状态就变为rejected,它的值是第一个被rejected的Promise对象的值。


Promise.all = function(promises) {
  return new Promise(function(resolve, reject) {
    var resolvedCounter = 0;
    var promiseNum = promises.length;
    var resolvedValues = new Array(promiseNum);
    for (var i = 0; i < promiseNum; i++) {
      (function(i) {
        Promise.resolve(promises[i]).then(function(value) {
          resolvedCounter++;
          resolvedValues[i] = value;
          if (resolvedCounter == promiseNum) {
            resolve(resolvedValues);
          }
        }, function(reason) {
          reject(reason);
        });
      })(i);
    }
  });
};
  1. Promise.race方法

Promise.race方法用于将多个Promise对象包装成一个新的Promise对象,当有一个Promise对象变为fulfilled或rejected时,新的Promise对象的状态就变为fulfilled或rejected,它的值是第一个变为fulfilled或rejected的Promise对象的值。

Promise.race = function(promises) {
  return new Promise(function(resolve, reject) {
    for (var i = 0; i < promises.length; i++) {
      Promise.resolve(promises[i]).then(function(value) {
        resolve(value);
      }, function(reason) {
        reject(reason);
      });
    }
  });
};