返回

浅谈promise原理及实现

前端

Promise原理

Promise是一种JavaScript对象,用于处理异步操作。它提供了一种简单而优雅的方式来处理异步操作的结果,并可以很容易地将多个异步操作连接在一起。

Promise有三种状态:pending、fulfilled和rejected。pending表示promise还没有完成,fulfilled表示promise已经成功完成,rejected表示promise已经失败。

当一个promise被创建时,它处于pending状态。当异步操作完成时,promise的状态会变成fulfilled或rejected,并调用相应的回调函数。

回调函数是当promise的状态改变时被调用的函数。回调函数有两个参数:resolve和reject。resolve函数用于将promise的状态变成fulfilled,reject函数用于将promise的状态变成rejected。

Promise实现

我们可以手写一个简单的promise来理解其内部的工作原理。

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

    const resolve = (value) => {
      if (this.state !== 'pending') return;
      this.state = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach((callback) => {
        callback(this.value);
      });
    };

    const reject = (reason) => {
      if (this.state !== 'pending') return;
      this.state = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach((callback) => {
        callback(this.reason);
      });
    };

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

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        setTimeout(() => {
          try {
            const value = onFulfilled(this.value);
            resolve(value);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else if (this.state === 'rejected') {
        setTimeout(() => {
          try {
            const reason = onRejected(this.reason);
            resolve(reason);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const value = onFulfilled(this.value);
              resolve(value);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const reason = onRejected(this.reason);
              resolve(reason);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });
  }

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

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

Promise的应用

Promise在实际开发中有很多应用场景,比如:

  • 并发请求:可以使用promise来并发发送多个请求,然后在所有请求完成后再执行后续操作。
  • 异步操作:可以使用promise来处理异步操作,比如读取文件、发送网络请求等。
  • 错误处理:可以使用promise来处理错误,并在错误发生时执行相应的操作。
  • 代码可读性:使用promise可以使代码更加易于阅读和理解。

总结

Promise是一种非常有用的工具,可以帮助我们编写更易于维护和理解的代码。它可以处理异步操作,并可以很容易地将多个异步操作连接在一起。