【问题标题】:How to wait for iteration to complete before returning如何在返回之前等待迭代完成
【发布时间】:2019-03-03 13:25:55
【问题描述】:

我正在尝试遍历 JSON 对象数组(var requestArray = req.body;,特别是 requestArray['filter']),将每个对象保存到数据库中。每次持久化后,我都会拉出最后一个持久化数据表,将其添加到responseDataArray.push(result); 中的数组let responseDataArray = [];。然后将该数组作为请求响应返回。

app.post('/sound', function (req, res) {
    var requestArray = req.body;

    let responseDataArray = [];

    for (var i = 0; i < requestArray['filter'].length; i++) {
        if (i > 3)
            break;

        var revEl = requestArray['filter'][i];
        // console.log('GUID >>> ' + i + ' : ' + revEl['_revEntityGUID'] + ' >>> ' + JSON.stringify(revEl));   

        persistSingleItemPromise(revEl).then(function (result) {
            responseDataArray.push(result);
            console.log(JSON.stringify(responseDataArray));
        });
    }

    console.log((responseDataArray));
    res.send(responseDataArray);
});

问题出在for loop。它延迟,我只返回一个空数组responseDataArray = [],因为它在迭代完成之前返回。

我尝试过使用Promose persistSingleItemPromise

let persistSingleItemPromise = function (revData) {

    return new Promise(function (resolve, reject) {
        revPersSaveRevEntity.revPersSaveRevEntity(revData, function (result) {
            resolve(result);
        });
    });
};  

这没有帮助。我该如何解决这个问题?

提前谢谢大家。

【问题讨论】:

  • 我认为您可能需要返回 resolved 结果。你可以在persistSingleItemPromise 中尝试return resolve(result); 吗?
  • 我认为你可以使用 reduce 并使用 promise 作为累加器,不幸的是我现在没有时间给你写一个例子。如果没有答案,我会稍后再回答。
  • 看看async/await
  • 您的代码似乎正确,所以我猜这是您的revPersSaveRevEntity 函数的问题。您是否检查过它是否提供了正确的结果?只需在resolve(result); 之前使用console.log(result)

标签: javascript arrays node.js promise iteration


【解决方案1】:

我在想这样的事情。

没有测试它是否有效请告诉我;-)

请记住,您的回调也需要异步前缀。

const resultPromise = requestArray['filter'].reduce( async ( accPromise, revEl ) => {
  const acc = await accPromise
  const result = await persistSingleItemPromise(revEl)
  acc.push( result )
  return result
}, Promise.resolve( [] ) )

const responseDataArray = await resultPromise

【讨论】:

    【解决方案2】:

    您可以使用Promise.all 并存储承诺。然后,等待他们全部解决

    喜欢

    app.post("/sound", function(req, res) {
      var requestArray = req.body;
    
      let responsePromises = [];
    
      for (var i = 0; i < requestArray["filter"].length; i++) {
        if (i > 3) break;
    
        var revEl = requestArray["filter"][i];
        // console.log('GUID >>> ' + i + ' : ' + revEl['_revEntityGUID'] + ' >>> ' + JSON.stringify(revEl));
    
        responsePromises.push(persistSingleItemPromise(revEl));
      }
    
      Promise.all(responsePromises).then(result => res.send(result));
    });
    

    这里是一个示例模拟

    const promises = [];
    for (let i = 1; i < 4; i++) {
      promises.push(new Promise(resolve => {
        // Simulate asynchronous request
        setTimeout(() => {
          resolve("Resolved " + i);
        }, 100 * i);
      }));
    }
    
    // Notice how the result takes some time.
    // It's basically waiting for all the promises to resolve
    Promise.all(promises).then(results => console.log(results));

    【讨论】:

    • 感谢@maaz-syed-adeeb 的回复,但我在哪里responseDataArray.push(result);
    • 你不需要。 result 变量将是一个包含所有 persistSingleItemPromise 结果的数组
    【解决方案3】:

    我认为您应该将“persistSingleItemPromise”中的所有承诺添加到数组中,并对它们执行 Promise.All(list).then() 并在返回之前等待结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2020-05-13
      • 2016-05-08
      • 2021-06-20
      • 1970-01-01
      相关资源
      最近更新 更多