【问题标题】:Reducing nested promises减少嵌套承诺
【发布时间】:2017-11-14 19:41:17
【问题描述】:

我正在通过以下方式减少一组嵌套的 Promise:

const promises = items.map((item, index) => {
    console.log(index);

    return doAsyncThing(item).then(() => {
       console.log(index);
    });
});

return promises.reduce((acc, p) => acc.then(() => p), Promise.resolve());

我希望打印出 console.log 条目

0 0 1 1 2 2

但他们正在打印出来

0 1 2 2 1 0

我怎样才能重组我的代码,以便在操作 1 之前完成整个操作 0,操作 1 在选项 2 之前完成,等等...?

【问题讨论】:

  • 您只需在上一次通话结束后拨打doAsyncThing()(在您的reduce 中)
  • i,... 不明白为什么在这里使用 reduce 而不是 promise.all,默认情况下会保留顺序。但是请注意,您正在记录的索引仍然会出现乱序,但 promise.all .then 回调中的结果将是有序的。
  • 你需要清楚地思考你实际上在做什么。一旦你有一个需要解决的承诺,就不需要在该承诺上调用then。此外,您想要的输出似乎表明您想要线性执行,而不是并发
  • 我不想使用Promise.all,因为我读到完成的承诺的顺序不能保证是连续的?这不正确吗?你是对的@smac89,我想要线性执行。
  • 您已经发送了请求,因此它们将同时发送,并以随机顺序完成。您可以使用 promise.all 来允许它继续进行,同时在完成所有操作后仍能以预期的顺序获得结果。如果您想一次只发送一个请求,则需要将您的 .map 替换为 .reduce,。

标签: javascript arrays promise


【解决方案1】:

问题

您的实现的问题是所有的 Promise 都是同时创建的,这将导致它们在那时将异步操作放入事件队列中。在您的情况下,这发生在 map 函数中。让我们来看看这个。

// your current code
const promises = items.map((item, index) => {
  console.log(index);       // this happens immediately and waits for nothing, which is why you see `0  1  2` in the console

  return doAsyncThing(item) // right here the async action is created
    .then(() => {           // this will run as soon as the async action is finished
      console.log(index);
    });
});

在这一步之后,promises 已经是一个 promise 数组,所有这些都已经将它们的异步操作排队,而不是等待任何其他的完成。

解决方案

您对 reduce 的想法是正确的,但是当您的 reduce 运行时,所有的 Promise 都已经创建,并且将按照它们完成的任何顺序运行。如果你想强制执行顺序,你首先需要使用 reduce 来创建 Promise:

const promises = items.reduce((acc, item, index) => {
  console.log(index) // still runs immediately
  return acc
    .then(() => doAsyncThing(item)) // creates the promise after acc finishes
    .then(() => console.log(index));    // runs after doAsyncThing finishes
}, Promise.resolve());

这将在您的控制台中生成输出0 1 2 0 1 2,但在操作 0 完成之前,操作 1 仍不会运行,而在操作 1 完成之前,操作 2 将不会运行。我希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    相关资源
    最近更新 更多