减少嵌套的承诺 [英] Reducing nested promises

查看:65
本文介绍了减少嵌套的承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过以下方式减少了嵌套的承诺数组:

I am reducing an array of nested promises in the following way:

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的全部,在选项之前完成操作0的全部2,等等...?

How can I restructure my code so that the entirety of operation 0 is completed before operation 1, which is completed before option 2, etc...?

推荐答案

问题



The实现的问题在于,所有的Promise都是在同一时间创建的,这将导致它们在那时将它们的异步操作放置在事件队列中。就您而言,这是在 map 函数中发生的。让我们看一看。

The Problem

The problem with your implementation is that all of the promises are created at the same time, and that will cause them to place their asynchronous actions in the event queue at that time. In your case, this is happening in the map function. Let's walk through this.

// 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);
    });
});

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

After this step, promises is already an array of promises, all of which have already queued up their asynchronous actions, not waiting for any others to be completed.

您对reduce有了正确的想法,但是到reduce运行时,所有promise已经创建,并且将以它们完成的顺序运行。如果要强制执行订单,则首先需要使用reduce来创建promise:

You have the right idea with the reduce, but by the time your reduce runs, all of the promises are already created, and will run in whatever order they finish. If you want to enforce order, you will need to use the reduce to create the promises initially:

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才运行。希望对您有所帮助!

This will produce the output 0 1 2 0 1 2 in your console, but action 1 will still not be run until action 0 finishes, and action 2 will not be run until action 1 finishes. I hope this helps!

这篇关于减少嵌套的承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆