Node.js中的异步生成器与异步迭代详解

Node.js中的异步生成器与异步迭代详解

异步迭代

异步迭代可以理解为一种异步操作处理流程,我们通过一个example框架来讲解其中的机制。

假设有这样一种场景,我们需要上传多张图片到远端服务器,并在所有的图片上传完成之后返回一个数组,数组中的每个元素为每一张图片上传成功后返回的结果。我们可以通过以下代码实现:

async function uploadPictures(pictures) {
  const results = [];
  for (const picture of pictures) {
    const result = await uploadPicture(picture);
    results.push(result);
  }
  return results;
}

上面的代码中使用了 for-of 循环来遍历 pictures 数组,每次遍历将图片上传到远端服务器,并将返回的结果 push 到 results 数组中。同时,使用 await 关键字等待每次异步操作完成后才进行下一次循环和操作。

但上面的代码存在一些问题,比如示例中的操作实际上是顺序执行的(同步运行),存在阻塞操作,当上传图片数量过多时,代码会因为阻塞而变得非常慢,降低系统的性能。为了解决这些问题,异步迭代应运而生。

使用异步迭代进行优化:

async function* uploadPictures(pictures) {
  for (const picture of pictures) {
    yield uploadPicture(picture);
  }
}

async function run() {
  const iterator = uploadPictures([1, 2, 3, 4, 5]);
  for await (const result of iterator) {
    console.log(result);
  }
}

上面的代码中,我们使用异步迭代器 async function* 重构了该函数的实现,将其变为一个生成器函数(generator function),其目的是让函数异步迭代图片上传的过程,即:

  1. 使用 yield 将每张图片上传操作返回,将该操作封装在生成器函数中。

  2. 使用异步迭代器遍历生成器函数,循环中的每一次异步操作都实现了异步执行(非阻塞)。

异步生成器

异步生成器是异步迭代的实现基础,它本身就是一个生成器函数,但可以通过 asyncawait 声明异步操作。在生成异步数据时,可以使用 yield 关键字将每个异步返回值返回到迭代器中,而异步操作执行完毕后也可以通过 return 关键字返回值,或者通过 throw 关键字抛出异常。

我们通过一个异步生成器的例子来帮助理解其机制:

async function* generateNumbers() {
  let i = 0;
  while (i < 5) {
    console.log('start');
    yield new Promise(resolve =>
      setTimeout(() => resolve(i++), 1000)
    );
    console.log('end');
  }
}

async function run() {
  const iterator = generateNumbers();
  for await (const number of iterator) {
    console.log(number);
  }
}

上面的代码中,通过异步生成器 generateNumbers() 实现异步生成 0-5 的整数,并使用异步迭代器 for await (const number of iterator) 获取异步生成器生成的每个值,并打印到控制台上。

需要注意的是,在 generateNumbers() 函数中使用了 yield new Promise(resolve => setTimeout(() => resolve(i++), 1000)); 这条语句的作用是暂停异步流程并等待该 Promise 对象的完成,然后再进一步执行下一步操作。

示例说明

异步迭代示例

我们继续使用上面的上传图片的示例来说明异步迭代的使用。

async function* uploadPictures(pictures) {
  for (const picture of pictures) {
    yield uploadPicture(picture);
  }
}

async function run() {
  const iterator = uploadPictures([1, 2, 3, 4, 5]);
  for await (const result of iterator) {
    console.log(result);
  }
}

上面的代码中,uploadPictures() 函数就是一个异步生成器,它将上传每一张图片的操作异步生成,然后使用异步迭代器遍历每次异步操作的结果,并将结果打印到控制台上。

异步生成器示例

我们再来看一个异步生成器示例,实现打印斐波那契数列前 n 项数。

async function* fibonacci(limit) {
  let [prev, curr] = [0, 1];
  for (let i = 0; i < limit; i++) {
    await new Promise(resolve => setTimeout(resolve, 1000));
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

async function run() {
  const iterator = fibonacci(10);
  for await (const number of iterator) {
    console.log(number);
  }
}

上述代码中,我们声明了一个异步生成器函数 fibonacci(),该函数生成了斐波那契数列的前 n 项,每次生成一个数值前会等待一秒钟,然后使用 yield 返回生成数据。最后在 run() 函数中使用异步迭代器遍历生成器函数返回的值,并将每个异步生成的值打印到控制台上。

使用异步生成器和异步迭代器可以更好地管理异步代码及其调度,使得代码更清晰、更可读且更易于调试。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Node.js中的异步生成器与异步迭代详解 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • NodeJS学习笔记之Connect中间件模块(二)

    NodeJS是目前最流行的服务器端JavaScript运行环境,其生态系统非常丰富,其中有一个重要的模块就是中间件(Connect Middleware)模块,它为Express和Koa等框架提供了基础设施。本文是“NodeJS学习笔记之Connect中间件模块(二)”,我将为大家详细讲解Connect模块的使用方法,让大家能够全面了解Connect模块的各…

    node js 2023年6月8日
    00
  • Sublime Text 3插件Minify的安装与使用(js代码压缩)

    下面是Sublime Text 3插件Minify的安装与使用攻略: 1. 安装Minify插件 在Sublime Text 3中安装插件可以通过Package Control来完成。如果你还没有安装它,请先安装Package Control插件,方法如下: 打开Sublime Text 3 按下Ctrl + ,(Windows)或⇧⌘P(Mac)打开命令面…

    node js 2023年6月8日
    00
  • Node.js 使用jade模板引擎的示例

    一、准备工作 安装 Node.js。 创建一个新的 Node.js 项目,使用 npm 初始化一个 package.json 文件,并安装 express 和 jade 依赖: $ npm init -y $ npm install express jade –save 二、创建一个使用 jade 模板引擎的简单应用 创建 index.js 文件,输入以下…

    node js 2023年6月8日
    00
  • 阿里云ecs服务器中安装部署node.js的步骤

    下面我将详细讲解在阿里云ECS服务器上安装部署Node.js的步骤。本攻略分为以下几步: 升级服务器 安装Node.js 部署Node.js应用 升级服务器 在开始安装Node.js之前,我们需要先升级服务器的软件包和依赖项。在终端中输入以下命令,进行升级: sudo apt-get update sudo apt-get upgrade 注意:以上命令是D…

    node js 2023年6月8日
    00
  • 详解PNPM Monorepo依赖项管理功能模拟实现

    什么是 PNPM Monorepo? PNPM Monorepo 是一个基于 PNPM 工具的多仓库(Monorepo)项目的依赖项管理工具。它可以帮助我们更好地管理项目的依赖项,保持项目的稳定运行。 PNPM Monorepo 的功能 PNPM Monorepo 的功能主要有: 更高效的依赖项安装方式,避免重复下载,减少磁盘空间占用 更快的构建和测试速度,…

    node js 2023年6月8日
    00
  • nodejs mysql 实现分页的方法

    接下来我会详细讲解“nodejs mysql 实现分页的方法”的完整攻略。 1. 实现分页的基本原理 在实现分页的过程中,其基本原理是:通过SQL语句获取总数据量和分页数据,从而计算出总页数,再通过LIMIT语句实现指定起始数据和每页数据量的数据获取。 示例SQL语句: SELECT COUNT(*) FROM table_name; // 获取总数据量 S…

    node js 2023年6月8日
    00
  • nodeJs爬虫的技术点总结

    请允许我以markdown文本形式详细讲解“nodeJs爬虫的技术点总结”的完整攻略,包括以下方面内容: 爬虫简介 爬虫主要是指通过程序自动化获取某些网站上的数据,并进行处理或存储。爬虫的基本流程通常包括抓取网页、解析网页、提取数据和存储数据。Node.js是一种非常适合来开发爬虫的技术,因为它提供了强大的异步I/O和处理大量数据的能力。 抓取网页 抓取网页…

    node js 2023年6月8日
    00
  • TypeScript手写一个简单的eslint插件实例

    下面是详细的攻略: 准备工作 安装相关依赖: npm install -D typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin 其中,typescript 是需要判断的语言,parser 是将代码解析成 AST(Abstract Syntax Tree)的工具,eslin…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部