javascript - 将变量重用到循环中 - NodeJS

标签 javascript node.js foreach

我是 Node.JS 的新手,我正在尝试在 Node.JS 中编写一个“同步”循环,理论上应该如下所示:

  1. 按顺序遍历一个对象数组
  2. 对每个对象应用一个函数(实际上 在数据库中创建对象并返回其唯一 ID)
  3. 创建第一个对象后,将其 id 作为所有其他对象的 parent_id。

问题是,我在回调和函数的异步/同步性质之间迷失了方向。例如。 ids.push 不会给出预期的结果。

编辑:另外,由于项目限制,我目前绑定(bind)到 Node 6.9。

代码暂定如下:

    function processAll( objectArray, callback ) {
        let ids = [];

        // Loop on all data
        objectArray.forEach( ( obj ) => {
            // From the second iteration on, 
            // objects are children of first obj 
            if( ids.length ) {
                obj.parent_id = ids[0];
            }
            someLib.doSomething( obj, ( err, result ) => {
                if( err ) {
                    return callback( err );
                }
                // This won't work, of course
                ids.push( result );
            });
        });
        return callback( null, ids );
    }

最佳答案

使用稍微不同的方法的另一个响应。

正如您正确提到的以及之前的一些答案也评论的那样,Array.prototype.forEach 不是异步感知的;它不会在进入下一次迭代之前等待项目准备就绪,而是尽快调用所有项目。

使用 promises 是一种很好的方法,但它需要您知道如何使用 promises 以及如何将旧式回调函数转换为 promise 函数。这已经出现在另一个答案中,所以我不会解释它。

我可以看到您的代码没有使用 promise,因此提供 promise 方法比帮助更令人困惑;相反,我会给你一个已经存在多年并经过实战测试的库的选项:Async .它使您能够非常轻松地执行异步操作,而无需为如何处理这些情况而绞尽脑汁。

在使用 npm install async 安装异步后,您实际上可以使用此代码片段在终端中查看结果。另外,我在模拟你的 someLib.doSomething 假设一个异步操作。

// Saved this code to a file named sync-loop.js for tests.
const async = require('async');
const items = [{ name: 'foo' }, { name: 'bar' }, { name: 'baz' }];

const someLib = {
  doSomething(obj, callback) {
    console.log('someLib.doSomething', obj);

    const randomValue = parseInt(Math.random() * 1000, 10);

    setTimeout(() => {
      callback(null, randomValue);
    }, randomValue);
  },
};

function processAll(objectArray, processAllCallback) {
  async.reduce(objectArray, [], (ids, item, reduceCallback) => {
    if (ids[0]) {
      item.parent_id = ids[0];
    }

    someLib.doSomething(item, (err, result) => {
      if (err) {
        reduceCallback(err);
      }

      ids.push(result);
      reduceCallback(null, ids);
    });
  },
    processAllCallback
  );
}

processAll(items, (err, ids) => console.log(ids));

运行此命令会得到类似的响应:

$ node sync-loop.js
someLib.doSomething { name: 'foo' }
someLib.doSomething { name: 'bar', parent_id: 145 }
someLib.doSomething { name: 'baz', parent_id: 145 }
[ 145, 179, 816 ]

关于javascript - 将变量重用到循环中 - NodeJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51842605/

相关文章:

php - foreach 语句强制 while/for 循环太多次

javascript - 获取不在同一行的两个字符串之间的字符串,正则表达式

node.js - 从 Twitter oAuth API 请求 token 时出现 215 错误

php - 为托管商中的 foreach php pdo 提供的参数无效

php - 在数组中推进索引键

mysql - NodeJS 与 mysql 的异步让我感到困惑

javascript - 如何在 JavaScript/jQuery 中转义字符?

javascript - 绑定(bind)多个参数的回调函数

javascript - 如何从javascript访问 react 内联样式

node.js - 在nodejs(express)中的router.route()中设置中间件