【问题标题】:Nested async await combined with loops嵌套异步等待与循环结合
【发布时间】:2020-04-12 17:12:39
【问题描述】:

编辑: 这是我的完整代码,不会引发任何错误:

router.get('/:id/all', async (req, res, next) => {
    let id = req.params.id;
    let t;                         
    let d;                         
    let o;                         
    let p;
    let data = [];
    let entry = {};
    try {
        let rowConfig = await methods.runQuery('SELECT SystemID, Begin, End, Power FROM Configuration WHERE ID = ?', id);
        p = rowConfig[0].Power;
        let begin = rowConfig[0].Begin;
        let end = rowConfig[0].End;
        let counter = [Var1, Var2, Var3];
        
        let result = await methods.runQuery('SELECT * FROM Table1 WHERE ID = ?', id);
        result.forEach(async function(row) {
            let resultT;
            if (!row.EventStop) {
                t = row.EventBegin - begin;
                resultT = await methods.runQuery('SELECT EventBegin, EventStop FROM Table1 WHERE ID = ? AND RootID IN (4, 5) AND IsValid = TRUE AND EventBegin < ?', [id, row.EventBegin]);
            }
            else {
                t = row.EventStop - begin;
                resultT = await methods.runQuery('SELECT EventBegin, EventStop FROM Table1 WHERE ID = ? AND RootID IN (4, 5) AND IsValid = TRUE AND EventBegin < ?', [id, row.EventStop]);
            }
            console.log(t);
            d = 0;
            resultT.forEach(function(row) {
                let dt = row.EventStop - row.EventBegin;
                d = d + dt;
            });
            o = t - d;
            console.log(o);
            entry = {'1': t, '2':o};
            data.push({entry});
        });
    } 
    catch (error) {
        res.status(500).send({ error: true, message: 'Error' });
    }
    return res.send({ data: data });
});

但是发送的数据数组仍然是空的!所以我查看了我的控制台,其中两个脱颖而出。

  1. to的值不对
  2. 当 get 方法已经完成时,它们会登录到控制台。所以发送数据数组的时候,里面显然是没有入口的。

代码应该执行的顺序:

对于 Table1 的每一行,我希望有 to,所以应该是:

forEach 循环(第 1 行)

-> if/else -> 计算 t

-> 得到结果T

-> forEach 循环 (row1)

-> 计算 d

-> forEach 循环 (row2)

-> 计算 d

-> ...

->计算o

-> 向数据推送条目

-> forEach 循环 (row2)

-> ...


我正在使用 node 和 express 来创建一个 Rest API。由于节点的异步行为,我目前正在苦苦挣扎。这就是我想要实现的目标:

在get方法中,我想从我的数据库中收集表的所有数据。

router.get('/:id/all', async (req, res, next) => {
...
try {
let result = await methods.runQuery('SELECT SystemID, Begin, End, Power FROM Configuration WHERE ID = ?', id);

runQuery 方法如下所示:

module.exports.runQuery = function(sql, parameter){
return new Promise((resolve, reject) => {
    dbConn.query(sql, parameter, function (error, result, fields) {
      if (error) reject(error);
      else {
        resolve(result);
      } 
    });
  });
}

到目前为止,这有效。现在我的问题开始了。 对于这张表的每一行,我都想做点什么。 在这个 for 循环中,我需要进行相互依赖的计算。 }

【问题讨论】:

  • 你能把整个逻辑放在一起吗?所以帮助会更容易......
  • 这是@SunnyParekh
  • 老实说,我看不出问题所在。你如何确保 B 最后被执行?您是否尝试登录result2
  • @Dijkstra 我更新了整个问题
  • @Dijkstra 谢谢,这是导致我所有问题的问题。如果您发布答案,我可以将其标记为已解决

标签: node.js express asynchronous promise


【解决方案1】:

javascript 中的for/forEach 循环不支持promise/async/await,因此您需要使用Promise.all 而不是for 循环。基本上是这样的

Promise.all(result.map(result => doSomethingAsync()))

确保结果中没有大量数据,因为您将并行旋转这些承诺。最好使用承诺批处理或流式处理。

【讨论】:

  • await inside .forEach 不起作用,但它会在 for, for..of 内部工作。
【解决方案2】:

正如我在评论中提到的,awaitforEach 循环中不起作用。改用for...of 循环。

例子:

for (let row of result) {
  // await will work here
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2018-06-25
    • 2020-10-17
    • 2018-06-04
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多