javascript - 嵌套的 forEach 循环存在异步问题,每次以不同的速率完成

标签 javascript express asynchronous foreach async-await

我正在使用express、neat-csv和mongoose,这导致我在从.csv文件进行批量注册调用时尝试检查是否存在一系列用户。如果您正确输入所有信息,下面的调用实际上可以完美运行。然而,它目前只能以不一致的速率捕获错误。为了测试的目的,我故意上传了一个我知道不符合要求的 .csv 文件(一些用户已经存在)。大多数时候它会运行得很好并返回仍然存在的用户列表。

不幸的是,无论如何,它都会以随机间隔返回完整的用户数组。我的代码如下。

//data是从neat-csv返回的数据,allUsers是所有用户id的数组,我正在检查数据库以查看是否有任何用户提前存在,然后再处理其他内容

  let Failed = false;          

  allUsers.forEach(async (id, index) => {
    await User.findById(id)
      .then(async users => {
        console.log('User', users);
        console.log('indexes', index, allPartners.length - 1)
        if (users === null && index !== allUsers.length - 1) return Failed = true;
        else if (users && Failed === false && index === allUsers.length - 1) {
          console.log('submitted indexes', index, allPartners.length - 1)
          data.forEach((user, i) => {
            console.log('Failed', Failed);
            if (i !== data.length - 1) user.addValue = 'newValue';
            else res.json(data).status(200);
          })
        } else if (index === allUsers.length - 1) {
          // process a failed search
        } else return Failed = true;
      })
      .catch(err => res.json({message: 'Failed to send a compatible .csv file.'}).status(401));
    });

从代码中的控制台日志中,返回以下内容。当它返回 2 2 时,这意味着它认为它已经位于数组的末尾,认为没有错误(因为它认为它已经检查了整个数组),然后将返回其余信息。

问题行是 else if (users && Failed === false && index === allUsers.length - 1) { 因为如果它认为它没有错误地到达末尾,那么它将运行。

[0] User {object}
[0] Failed false
[0] indexes 2 2
[0] submitted indexes 2 2
[0] User null
[0] Failed false
[0] indexes 0 2
[0] User null
[0] Failed true
[0] indexes 1 2

我确信这个问题与 javascript 在处理嵌套循环时的异步行为有关。我尝试添加一些异步等待,但这并没有改变任何东西。有没有办法强制 javascript 等待第一个循环完成,如果成功,它可以返回我可以检查的值,这样我就不需要以我的方式嵌套循环。或者只是保证循环同步运行?

我对 es6+ 或 bluebird 理想的解决方案持开放态度,但任何建议我都会感激不尽。

最佳答案

免责声明:此回复旨在为您指明正确的方向,而不是提供准确的答案。

首先,您的查询可以更加高效。当你可以告诉 Mongo 搜索整个数组时,为什么还要自己遍历数组呢?

查看$in运算符。

下面是伪代码,它做出以下假设:1) Mongo 查询的措辞类似,纯粹基于 .find() 的文档; 2)User是一个Mongo集合。

const allUsers = getIdsFromCSV(filename);

async function anyUsersAlreadyExist() {
    const users = await User.find({ id: { $in: allUsers } }).toArray();

    return users.length > 0;
};

const failed = anyUsersAlreadyExist();

关于javascript - 嵌套的 forEach 循环存在异步问题,每次以不同的速率完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49439810/

相关文章:

c# - Task<int> 是如何变成一个 int 的?

javascript - 为什么我不能用 javascript 同时更改图像的高度和宽度?

javascript - jQuery 获取数据名称作为值

javascript - blob 显示为字节串( Angular + Express )

node.js - 使用 Firebase Cloud Functions 实现 REST 接口(interface)

multithreading - Lwt.async() 未按预期工作

javascript - 如何使用纯 Javascript 使 HTML 元素可调整大小?

使用 setTimeout/异步输出的 Javascript 编码挑战

node.js - 如何处理在 Nodejs 中多次调用 server.handleUpgrade()?

java - 如何立即更新线程之间的共享变量