0

我目前正在开发一个程序,我需要使用 Promise.all 同时运行几个功能。但是在我可以继续执行任务之前,我只需要完成 2 个承诺然后运行 ​​.then(),我该怎么做呢?

例子:

await Promise.all([Task1(),Task2(),Task3(),Task4(),Task5()]);

当仅(例如)Task1 和 Task 4 完成时,我需要它来继续代码。

我试图通过使用 while 循环等待 Task1 和 Task2 通过在完成时设置变量完成来进行试验,但是那样。根本不起作用。

4

5 回答 5

4

在评论中,您似乎说过您事先特别知道哪两个比其余的更紧急(在本例中,它是 Task1 和 Task4)。

然后只需使用Promise.all两次:

const allResults = Promise.all([
    Promise.all([Task1(), Task4()])
    .then(([result1, result4]) => {
        // Those two are done, do what you like with `result1` and `result4`...
        return [result1, result4];
    }),
    Task2(),
    Task3(),
    Task5()
])
.then(([[result1, result4], result2, result3, result5]) => {
    // All five are done now, let's put them in order
    return [result1, result2, result3, result4, result5];
})
.then(/*...*/)
.catch(/*...*/);

then在那里,我通过重新映射整个处理程序中的顺序来保留外链中的整体 1、2、3、4、5 顺序。


最初,我假设您想等到任何两个完成,而不是特定的两个。没有内置的,但它很容易编写:

function enough(promises, min) {
  if (typeof min !== "number") {
    return Promise.all(promises);
  }
  let counter = 0;
  const results = [];
  return new Promise((resolve, reject) => {
    let index = 0;
    for (const promise of promises) {
      let position = index++;
      promise.then(
        result => {
          results[position] = result;
          if (++counter >= min) {
            resolve(results);
          }
        },
        reject
      );
    }
  });
}

现场示例:

function enough(promises, min) {
  if (typeof min !== "number") {
    return Promise.all(promises);
  }
  let counter = 0;
  const results = [];
  return new Promise((resolve, reject) => {
    let index = 0;
    for (const promise of promises) {
      let position = index++;
      promise.then(
        result => {
          results[position] = result;
          if (++counter >= min) {
            resolve(results);
          }
        },
        reject
      );
    }
  });
}

const delay = (ms, ...args) => new Promise(resolve => setTimeout(resolve, ms, ...args));
const rnd = () => Math.random() * 1000;

enough(
  [
    delay(rnd(), "a"),
    delay(rnd(), "b"),
    delay(rnd(), "c"),
    delay(rnd(), "d"),
    delay(rnd(), "e")
  ],
  2
)
.then(results => {
  console.log(results);
})
.catch(error => {
  console.error(error);
});

于 2019-04-10T11:26:16.647 回答
1

一种方法是构造一个新的随机承诺数组,然后只等待那些:

let array = [Task1(),Task2(),Task3(),Task4(),Task5()];

// Select any two promises after running the randomization logic
let promises = Promise.all[array[1], array[3]];

promises
  .then(() => {
    // Do stuff here
  });
于 2019-04-10T11:23:27.627 回答
0

Promise.all()不会同时运行您的任务,它只等待所有 Promise 解决,然后再解决返回的 Promise。

您的任务将在您创建每个 Promise 后立即运行。

如果您想在完成特定任务后等待,请仅将这些任务包含在Promise.all

const tasks = [Task2(), Task3(), Task5()];
const result1 = await Promise.all([Task1(), Task4()]);
// Task1 and Task4 are done here
const result2 = await Promise.all(tasks);
// All remaining tasks are done here
于 2019-04-10T11:22:04.977 回答
0

好的,据我了解,您想做类似的事情

const importantOnes = [Task1(), Task2()];
const remainingOnes = [Task3(), Task4(), Task5()];
const priorityPromise = Promise.all(importantOnes);

priorityPromise.then(doPriorityStuff);
Promise.all([priorityPromise, ...remainingOnes]).then(processTheCompleteData);
于 2019-04-10T11:29:51.387 回答
0

我见过这样的技巧: Promise.all(promises.map(p => p.catch(() => undefined))); 虽然很不安全。
原始答案:这里

于 2019-04-10T11:25:54.803 回答