LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

在 JavaScript 中映射 Promises

admin
2024年12月30日 21:15 本文热度 99

你是否遇到过这样的情况:你期望你的 map 函数返回一个已解决/等待的值,但它却返回了一个包含多个 promises 的列表。例如:

const result = ids.map(async (id) => {
  return await fetch(id);
});

// 期望结果:[{ name: "Adam" }, { name: "Linda" }]
// 实际结果:[Promise {<pending>}, Promise {<pending>}, ...]

你并不孤单。我在配对编程中也遇到过这种情况几次。本文将展示如何在 async/await 操作中进行映射。

准备好了吗?让我们开始。

问题

想象一下:你拿到了一个需要异步处理的项目数组。也许这些项目代表 ID,你需要为每个 ID 获取数据。这是一个常见的错误:

const ids = [12345];

const fetchData = async (id) => {
  // 模拟异步获取操作
  return `data for ${id}`;
};

const processItems = async () => {
  const result = ids.map(async (id) => {
    return await fetchData(id);
  });

  console.log(result); // [Promise {<pending>}, Promise {<pending>}, ...]
};

processItems();

好的,这里出了什么问题呢?🤔 map 函数返回了一个 promises 数组,并没有等待它们解决。这不是我们想要的,并且在稍后尝试使用 result 时可能会导致混乱。

for…of 循环解决方案

一种方法是使用 for...of 循环。如果你的异步操作需要按顺序发生而不是并行执行,这将非常有用。

const processItemsSequentially = async () => {
  const result = [];
  for (const id of ids) {
    const data = await fetchData(id);
    result.push(data);
  }

  console.log(result); // ['data for 1', 'data for 2', ...]
};

processItemsSequentially();

如果你的目标是顺序执行,这将更容易阅读和理解,但要小心——这种方法可能会更慢,因为每个操作都等待前一个操作完成。

Promise.all 解决方案

让我们使用 Promise.all 和 Array.prototype.map() 来清理这个问题。这个巧妙的方法可以将我们的 promises 数组包装成一个单一的 promise,当所有 promises 解决时,它将解决。

const processItems = async () => {
  const result = await Promise.all(
    ids.map((id) => {
      return fetchData(id);
    })
  );

  console.log(result); // ['data for 1', 'data for 2', ...]
};

processItems();

太好了!现在我们正在高效地工作。promises 数组被包装在一个单一的 promise 中,它将用结果解决。好多了,并且是并发运行的!然而,有一个问题。并发运行 promises(例如,有 1000 个项目)并不总是意味着快速。它可能会变慢,并可能导致内存问题。

提示:你可以选择在这个例子中使用 promise.all() 或 promise.allSettled()。

使用 p-map 的更清晰解决方案

最后,让我们看看一个更好的并发映射方法,同时限制应该同时运行的 promises 数量。为此,我们将使用 npm 上的 p-map。你可以使用 npm install p-map 将其添加到你的项目中。

它与 Promise.all() 不同,因为你可以控制并发限制,并决定在出现错误时是否停止迭代。以下是我们定义的 processItems() 函数的样子:

import pMap from 'p-map';
const ids = [12345];

const fetchData = async (id: number) => {
  // 模拟异步获取操作
  return `data for ${id}`;
};

const processItems = async () => {
  const result = await pMap(ids, (id) => fetchData(id), { concurrency2 });

  console.log(result); // ['data for 1', 'data for 2', ...]
};

processItems();

虽然我们在这里使用了不同的语法,但这个版本是简洁有效的。通过设置并发限制,这种模式避免了在有大量数据时系统过载,并且我们可以控制在出现错误时是否停止或继续。有关 p-map 的更多选项,请查看 GitHub 上的文档。

结论

就是这样,朋友们!我们探讨了在映射 promises 时的一个常见错误,并涵盖了三种有效的解决方案:

  1. 使用 for...of 进行顺序操作 🌀
  2. 使用 Promise.all 进行并行执行 👌🏽
  3. 使用 p-map 模块的更清晰解决方案 🌟

我希望这能帮助你成为一个Promise映射专家!编码愉快!🎉


原文地址:https://www.telerik.com/blogs/mapping-promises-javascript


阅读原文:原文链接


该文章在 2024/12/31 11:37:53 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved