返回

Promise的实现方法及其链式调用的要点

前端

Promise的实现

Promise是一个类,可以用来创建异步操作。Promise的构造函数接受一个参数,这个参数是一个函数,叫做执行器函数(executor)。执行器函数有两个参数,分别是resolve和reject。resolve表示异步操作成功,reject表示异步操作失败。

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.value = null;
    this.error = null;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

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

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      this.onFulfilledCallbacks.push(() => {
        try {
          const value = onFulfilled(this.value);
          resolve(value);
        } catch (err) {
          reject(err);
        }
      });

      this.onRejectedCallbacks.push(() => {
        try {
          const error = onRejected(this.error);
          resolve(error);
        } catch (err) {
          reject(err);
        }
      });
    });
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }

  finally(onFinally) {
    return this.then(
      (value) => {
        onFinally();
        return value;
      },
      (error) => {
        onFinally();
        throw error;
      }
    );
  }

  resolve(value) {
    if (this.state !== 'pending') {
      return;
    }

    this.state = 'fulfilled';
    this.value = value;

    this.onFulfilledCallbacks.forEach((callback) => {
      callback();
    });
  }

  reject(error) {
    if (this.state !== 'pending') {
      return;
    }

    this.state = 'rejected';
    this.error = error;

    this.onRejectedCallbacks.forEach((callback) => {
      callback();
    });
  }
}

链式调用的要点

Promise的链式调用可以通过then方法实现。then方法接受两个参数,分别是onFulfilled和onRejected。onFulfilled表示异步操作成功时的回调函数,onRejected表示异步操作失败时的回调函数。

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello, world!');
  }, 1000);
});

promise
  .then((value) => {
    console.log(value); // 'Hello, world!'
  })
  .catch((error) => {
    console.error(error);
  });

链式调用的要点在于,then方法返回一个新的Promise。这个新的Promise的状态取决于onFulfilled和onRejected回调函数的返回值。如果onFulfilled回调函数返回一个值,那么新的Promise的状态为fulfilled,返回值为onFulfilled回调函数的返回值。如果onFulfilled回调函数抛出一个错误,那么新的Promise的状态为rejected,错误原因为onFulfilled回调函数抛出的错误。

链式调用可以让代码看起来更简洁,易于阅读。例如,以下代码实现了获取用户信息的异步操作:

const getUserInfo = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        name: 'John Doe',
        age: 30,
      });
    }, 1000);
  });
};

getUserInfo()
  .then((user) => {
    console.log(user.name); // 'John Doe'
  })
  .catch((error) => {
    console.error(error);
  });

如果我们不使用链式调用,那么代码就会变得很长,而且很难阅读。

getUserInfo().then((user) => {
  console.log(user.name);
}).catch((error) => {
  console.error(error);
});

结语

Promise是一种非常有用的类,可以用来替代回调函数处理异步操作。Promise的链式调用可以让代码看起来更简洁,易于阅读。本文介绍了如何实现Promise,并详细分析了链式调用的要点。