等待循环结束

发布于 2025-02-11 11:03:37 字数 745 浏览 2 评论 0原文

我有一个箭头函数,该功能将两个数组作为参数,然后在某些条件下我将项目从第二个数组推到第一个数组。

问题是我有大量的数据,我应该推出和res.send无法等待循环结束并向我发送有关内存的错误JavaScript堆

我如何在循环结束并使循环更快地工作时如何等待?我只是尝试异步/等待,promiseall,等待

let mergeById = async(arr1, arr2) => {
  arr1.map(async(item) => {
    item.properties = [];
    await arr2.map(async(prop) => {
      if (item.item_id == prop.item_id) {
        await item.properties.push(prop);
      }
    })
  })
  return arr1
}

async someFunction(req, res) {

  arr1 = dataItems(); //6000 items
  arr2 = dataProps(); //60000 items

  let result = await mergeById(arr1, arr2);

  res.json({
    data: result
  })

}

I have an arrow function which get two arrays as parameters then on certain condition i push items from second array to first array

The problem is that i have big amount of data that i should to push and res.send cant wait while loop is over and send me error about memory JavaScript heap out of memory

How i can wait while my loop is over and make loop to work faster? I just try with async/await, promiseAll, for await

let mergeById = async(arr1, arr2) => {
  arr1.map(async(item) => {
    item.properties = [];
    await arr2.map(async(prop) => {
      if (item.item_id == prop.item_id) {
        await item.properties.push(prop);
      }
    })
  })
  return arr1
}

async someFunction(req, res) {

  arr1 = dataItems(); //6000 items
  arr2 = dataProps(); //60000 items

  let result = await mergeById(arr1, arr2);

  res.json({
    data: result
  })

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单身情人 2025-02-18 11:03:37

您在映射中具有映射,因此对于Array1中的每个项目,它都会在整个数组2上迭代。对于计算机而言并不是那么多),您会遇到巨大的影响。因为您必须进行6 000 * 60 000 = 360,000,000迭代,所以

有一个解决方案。您必须进行一些预处理 - 创建for Array2的新映射()在所有项目上迭代,然后将item_id作为键true保存为键。类似array2map.set(prop.item_id,prop)

然后更改周期以检查您的地图

arr1.map(async(item) => {
    item.properties = [];
    const prop = array2Map.get(item.item_id);
    if (prop) {
        item.properties.push(prop)
    }

,现在您拥有o(n * log n)复杂性代码> o(n)由于哈希图的伪线性复杂性,但这是不同的故事,现在并不重要)。那对您的用例就足够了。


另外,使用等待async的另一个问题。只需从您提出的所有代码中删除所有这些用法即可。它没有做任何有用的事情,但实际上会破坏几件事。

.map函数无论是否将async函数作为参数进行同步运行。它只会创造一系列承诺。除非您确切地知道自己在做什么,否则我的提示是,对于数组函数(映射,前部,减少等),永远不要将异步功能用作参数 - 因为它大多是您预期的不起作用。

You have map inside map, therefore for each item in array1 it will iterate over whole array 2. You have encountered O(n^2) complexity and as you can see - even with 66 000 items (which is not that much for computer on its own), you are encountering huge impact. Because you have to do 6 000 * 60 000 = 360,000,000 iterations

There is a solution. You have to do some preprocessing - create new Map() for array2, iterate over all items and save item_id as a key with value true. Something like array2Map.set(prop.item_id, prop)

Then change your cycle to check your map

arr1.map(async(item) => {
    item.properties = [];
    const prop = array2Map.get(item.item_id);
    if (prop) {
        item.properties.push(prop)
    }

Now you have O(n * log n) complexity (well its almost O(n) because of pseudo-linear complexity of hashmaps, but thats different story, not that important now). And thats good enough for your use-case.


Also there is another problem with usage of the await and async. Just remove all this usage from all the code you have presented. It does not do anything useful, but actually breaks few things.

.map function runs synchronously no matter if you put async function as a parameter. It will just create an array of promises. Unless you know exactly what you are doing, my tip is that for array functions (map, foreEach, reduce etc.) never ever use async function as parameter - as it will mostly not work as you expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文