返回

从小白视角快速上手 Promise、Async/await,并实现手撕代码

前端

JavaScript 的世界,从小白到高手,你我皆可为王。

写在前面
在前端开发中,我们经常会遇到异步操作,比如网络请求、定时器等。这些操作的特点是,它们不会立即返回结果,而是需要等待一段时间后才能得到结果。为了处理异步操作,我们可以使用回调函数、Promise和Async/await等方式。

本文将从小白的角度出发,带你快速上手Promise、Async/await,并实现手撕代码。

一、异步操作与回调函数

异步操作是指不会立即返回结果的操作,比如网络请求、定时器等。这些操作需要等待一段时间后才能得到结果。

回调函数是指当异步操作完成时被调用的函数。回调函数通常作为异步操作函数的参数传入。当异步操作完成时,异步操作函数会调用回调函数,并将结果作为参数传递给回调函数。

回调函数的写法如下:

function callback(result) {
  // 异步操作完成后的处理逻辑
}

二、Promise

Promise是一种用于处理异步操作的更高级的方式。Promise对象代表一个异步操作的结果,它可以处于三种状态:

  • pending(等待): 异步操作尚未完成。
  • fulfilled(已完成): 异步操作已完成,并且成功返回了结果。
  • rejected(已拒绝): 异步操作已完成,并且失败了。

我们可以使用Promise对象的then方法来处理异步操作的结果。then方法接受两个参数,分别是fulfilledHandler和rejectedHandler。当异步操作成功完成时,fulfilledHandler会被调用,并接收异步操作的结果作为参数。当异步操作失败时,rejectedHandler会被调用,并接收异步操作的错误信息作为参数。

Promise对象的写法如下:

const promise = new Promise((resolve, reject) => {
  // 异步操作
  if (success) {
    resolve(result);
  } else {
    reject(error);
  }
});

promise.then(fulfilledHandler, rejectedHandler);

三、Async/await

Async/await是ES8中引入的异步编程语法。Async/await可以使异步代码看起来像同步代码一样。

要使用Async/await,我们需要先使用async声明一个函数。在async函数中,我们可以使用await关键字来等待异步操作完成。await关键字后面的表达式必须是一个Promise对象。当await关键字后面的Promise对象完成时,await关键字后面的代码才会执行。

Async/await的写法如下:

async function myFunction() {
  const result = await promise;
  // 异步操作完成后的处理逻辑
}

四、手撕代码

手撕代码是指不使用任何库或框架,自己实现代码。我们可以使用手撕代码来实现Promise和Async/await。

实现Promise

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

    const resolve = (result) => {
      if (this.state !== 'pending') return;

      this.state = 'fulfilled';
      this.result = result;
      this.onFulfilledCallbacks.forEach(callback => callback(result));
    };

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

      this.state = 'rejected';
      this.result = error;
      this.onRejectedCallbacks.forEach(callback => callback(error));
    };

    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        onFulfilled(this.result);
      } else if (this.state === 'rejected') {
        onRejected(this.result);
      } else {
        this.onFulfilledCallbacks.push(() => {
          onFulfilled(this.result);
        });
        this.onRejectedCallbacks.push(() => {
          onRejected(this.result);
        });
      }
    });
  }
}

实现Async/await

function asyncFunction(generator) {
  return new Promise((resolve, reject) => {
    const gen = generator();

    function handleNext(value) {
      const result = gen.next(value);
      if (result.done) {
        resolve(result.value);
      } else {
        result.value.then(handleNext, handleReject);
      }
    }

    function handleReject(error) {
      gen.throw(error);
    }

    handleNext();
  });
}

五、总结

Promise和Async/await都是处理异步操作的有效方法。Promise对象可以表示异步操作的结果,并可以使用then方法来处理异步操作的结果。Async/await可以使异步代码看起来像同步代码一样。

本文从小白的角度出发,带你快速上手Promise、Async/await,并实现手撕代码。希望本文对你有帮助。