跳转至

JavaScript 异步函数处理方法详解

本文介绍两种常用的 JavaScript 异步处理方法:异步函数包装器和异步迭代器。

异步函数包装器

异步函数包装器用于统一处理异步函数的返回值和异常,避免在每个异步操作中重复编写 try-catch 代码块。

/**
 * 异步函数包装器,用于统一处理异步函数的返回值和异常
 * @param {Promise} promise - 一个Promise对象
 * @returns {Array} - 返回一个数组,第一个元素是Promise的解析结果,第二个元素是捕获到的异常
 */
export const asyncWrapper = async (promise) => {
  try {
    // 等待Promise解析,并返回解析结果
    const result = await promise; // 修正拼写错误:reault -> result
    // 成功时返回解析结果和null
    return [result, null];
  } catch (e) {
    // 失败时返回null和异常对象
    return [null, e];
  }
};

使用示例

// 使用 asyncWrapper 处理异步操作
const [data, error] = await asyncWrapper(fetch('/api/data'));

if (error) {
  console.error('请求失败:', error);
} else {
  console.log('请求成功:', data);
}

异步迭代器

异步迭代器允许我们以异步方式迭代数据,每次迭代之间可以有异步操作。下面的示例每隔2秒输出1到5的数字。

const asyncRange = {
  from: 1,
  to: 5,
  [Symbol.asyncIterator]() {
    return {
      current: this.from,
      last: this.to,
      async next() {
        await new Promise(resolve => setTimeout(resolve, 2000));
        if (this.current <= this.last) {
          return {
            done: false,
            value: this.current++,
          };
        } else {
          return {
            done: true,
          };
        }
      },
    };
  },
};

(async () => {
  for await (const n of asyncRange) {
    console.log(n);
  }
})();

代码说明

  1. Symbol.asyncIterator 是用于定义异步迭代器的特殊符号
  2. for await...of 语句用于遍历异步可迭代对象
  3. 每次迭代之间会等待2秒,模拟异步操作

优势

  • 异步包装器:简化错误处理,避免重复的 try-catch 代码
  • 异步迭代器:允许在迭代过程中执行异步操作,提供更灵活的数据处理方式

注意事项

  1. 在使用 asyncWrapper 时,要确保传入的是 Promise 对象
  2. 异步迭代器适用于需要在迭代过程中执行异步操作的场景
  3. 在生产环境中,应考虑错误处理和资源清理