【问题标题】:Reduce method and promises减少方法和承诺
【发布时间】:2021-09-04 08:07:02
【问题描述】:

我在使用 _.reduce 和 promises 时遇到问题。

我需要使用 Promise 来获取我的项目,并且我想使用 _.reduce 使用其他 Promise 修改结果的内容。

我的代码:

StripeJs.getBalanceTransactions = function(locals, gte, lte) {
  return stripe.balanceTransactions.list().then(function(balanceTransactions) {

    let payoutsBalanceTransactions = _.filter(balanceTransactions.data, { type: 'payout' });

    payoutsBalanceTransactions = _.reduce(payoutsBalanceTransactions, function(arr, payoutBalanceTransaction) {
      stripe.balanceTransactions.retrieve(payoutBalanceTransaction.id).then(function(subItems) {
        payoutBalanceTransaction.subitems = subItems;

        console.log(payoutBalanceTransaction); // works !

        arr.push(balanceTransactions);
      });
      return arr;
    }, []);

    console.log(payoutsBalanceTransactions); // does not work, array empty

    return Promise.resolve(payoutsBalanceTransactions);
  });
};

【问题讨论】:

  • 问题在于异步 - 在任何 .then(function(subItems) { 代码运行之前,reduce 将一直执行 - 将一些 console.logs 放在那里,看看我是对的
  • 我没有看到你减少任何东西,如果你只想等待一系列承诺,请使用Promise.all
  • 您是否使用reduce 以便每个stripe.balanceTransactions.retrieve 在前一个完成后运行?即它们可以“一次全部”运行,还是一次运行一个?
  • 顺便问一下,arr.push(balanceTransactions); 应该是 arr.push(payoutBalanceTransaction) 吗?多次推送balanceTransactions 似乎很奇怪

标签: javascript promise lodash reduce


【解决方案1】:

您当前代码的问题是您将结果推送到异步回调中的数组中。因此,payoutsBalanceTransactions 数组在触发回调之前一直为空。你console.log(payoutsBalanceTransactions)数组之前的内容被填满了,所以数组是空的。

如果您不介意使用async/await,最干净的解决方案可能是:

StripeJs.getBalanceTransactions = async function (locals, gte, lte) {
  const transaction = await stripe.balanceTransactions.list();
  const payouts = _.filter(transactions, { type: 'payout' });

  await Promise.all(payouts.map(async function (payout) {
    const items = await stripe.balanceTransactions.retrieve(payout.id);
    payout.subitems = items;
  }));

  console.log(payouts);

  return payouts;
};

我已经重命名了一些变量,因为其中一些变量很长。如果你不能或不想使用async/await,事情就会变得有点棘手。

StripeJs.getBalanceTransactions = function (locals, gte, lte) {
  return stripe.balanceTransactions.list()
  .then(function (transactions) {
    const payouts = _.filter(transactions, { type: 'payout' });
    return Promise.all(payouts.map(function (payout) {
      return stripe.balanceTransactions.retrieve(payout.id)
      .then(function (items) {
        payout.subitems = items;
        return payout;
      });
    }));
  })
  // This last `then()` is only here for logging, you can remove it
  // entirely if you don't need the `console.log()` any more.
  .then(function (payouts) {
    console.log(payouts);
    return payouts;
  });
};

为了更好地理解 Promise 和一般的异步代码,我建议阅读 Using Promises guide。

【讨论】:

    猜你喜欢
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-27
    相关资源
    最近更新 更多