【问题标题】:multiple Promises in nodejs wait till they all finishnodejs中的多个Promise等到它们全部完成
【发布时间】:2020-09-18 22:12:01
【问题描述】:

我的 nodejs 应用程序中有这段 sn-p 代码。

问题在于它在呈现配置页面并传递对象 thebalances 之前没有等待。

app.get("/config", (req, res) => {
    var thebalances = [];
    client.rest.account.listAccounts().then(accounts => {

        accounts.forEach(element => {
            client.rest.product.getProductTicker(element.currency + '-USD').then(priceInfo => {

                thebalances.push({
                    currency: element.currency
            });
        });
        res.render("config", { balance: thebalances });
    })
});

我现在已将其修改为:但我认为它在某些方面出错了,就像下面提到的那样,它都失败了。

// GET /about
app.get("/config", (req, res) => {
    let thebalances = [];
    client.rest.account.listAccounts().then(async accounts => {
        let promises = [];
        accounts.forEach(element => {
            promises.push(client.rest.product.getProductTicker(element.currency + '-USD'));
        });
        await Promise.all(promises).then(
            results => {
                results.forEach(priceInfo => {
                    thebalances.push({ currency: element.currency });
                });
            }
        ).catch(
            error => {}
        )
        console.log(results);
        res.render("config", { balances: thebalances });
    })
});

我不确定如何在 foreach 循环中处理多个变量#。在渲染配置页面之前,我需要先让它完成它的工作。

任何帮助将不胜感激。我正在使用 coinbase api。

【问题讨论】:

  • 你需要使用Promise.all
  • 但它的承诺数量未知,因此在 forEach 循环中它可能是 3 可能是 30 我将如何构建它?
  • promise 的数量不需要固定,任何账户数组都可以:Promise.all(accounts.map(...))
  • 好的,我理解 promise.all 文档,但不清楚我将如何在我的特定场景中使用它,你提到了 accounts.map
  • 很难建议。正如目前所写的那样,您会很麻烦地获取各种priceInfo,但随后不要使用它。大概应该呈现priceInfo 或其某些属性?

标签: node.js promise coinbase-api


【解决方案1】:
client.rest.account.listAccounts().then(async accounts => {
    let promises = [];
    accounts.forEach(element => {
        promises.push(client.rest.product.getProductTicker(element.currency + '-USD'));
    });
    await Promise.all(promises).then(
        results => {
            results.forEach(priceInfo  => {
                thebalances.push({currency: element.currency});
            });
        }
    ).catch(
        error => {
        }
    )
    res.render("config", { balance: thebalances });

请阅读此内容...https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

如果一个失败就失败,使用 Promise.all 会有一些弊端。

编辑:缺少等待

【讨论】:

  • 我认为这可能是正在发生的事情,我无法控制台记录任何结果或变量 thebalances
  • 如果一个人失败了,我将如何解决它作为一个整体失败?
  • 查看 Promise all 文档底部的 #Promise.all 快速失败行为
【解决方案2】:

如果确实存在一个或多个 promise 失败的情况,并且从应用程序的角度来看确实没问题,那么...

// ...
let promises = accounts.map(element => {
    return getProductTicker(element.currency);
});
// ...


function getProductTicker(currency) {
    return client.rest.product.getProductTicker(currency + '-USD').catch(error => {
        // debug here, if the error is a problem, otherwise
        return null
    })
}

现在 promise all 将包含getProductTicker 的正确分辨率以及调用失败的空值。要清理它...

await Promise.all(promises).then(results => {
    let maybeWeShouldDebugHere = results.filter(r => !!!r)
})

【讨论】:

  • 嗯,这看起来会改变我的 sn-p,你能把你的建议落实到我的 sn-p 中看看它会是什么样子吗
猜你喜欢
  • 2014-09-20
  • 2020-12-14
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多