Могу ли я вставить новое обещание в массив в середине Promise.all ()? - PullRequest
1 голос
/ 26 октября 2019

Я пытаюсь понять, как работает Promise.all. Мой вопрос: это нормально, чтобы вставить новое обещание в середине Promise.all () в тот же массив, который был передан ранее? Например, у меня есть этот код, который прекрасно работает: https://jsfiddle.net/artheg/z0Lndw1o/14/

const promises = [];
const promise1 = new Promise(function(resolve, reject) {
  resolve('promise1');
  const promise2 = new Promise(function(resolve, reject) {
    resolve('promise2');
  });
  pushPromise(promise2); // Pushing promise2 to the same array after the promise1 was resolved
});

pushPromise(promise1); // Pushing promise1

function pushPromise(promise) {
  promises.push(promise);
}

Promise.all(promises).then(function(values) {
  console.log(values); // Array [ "promise2", "promise1" ]
});

Предназначено ли это поведение или я всегда должен связывать обещания с .then () вместо того, чтобы вставлять новое обещание в массив?

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Код в исполнителе обещаний (функция, которую вы передаете new Promise) запускает синхронно . Итак, pushPromise(promise2) уже запущен до того, как вы позвоните Promise.all. Массив уже заполнен к тому времени, когда вы вызываете Promise.all.

Могу ли я вставить новое обещание в массив в середине Promise.all ()?

Неесли вы хотите, чтобы Promise.all увидел это обещание, нет. См. спецификация , Promise.all циклически повторяет итеративную передачу, которую вы передаете синхронно, перед возвратом, и перед тем, как могут быть вызваны любые обработчики, которые она (Promise.all) настраивает на посылы.

Вот пример, обратите внимание, что обещание от Promise.all выполняется, а не отклоняется, хотя код добавляет обещание к массиву, который он отклоняет:

const promises = [
    Promise.resolve(1),
    Promise.resolve(2).finally(() => {
        promises.push(Promise.reject(new Error("failed")));
    }),
    Promise.resolve(3),
];
Promise.all(promises)
.then(results => {
    console.log(`results (${results.length}): ${results.join(", ")}`);
    console.log(`promises.length: ${promises.length}`);
})
.catch(error => {
    console.error(error);
});
1 голос
/ 26 октября 2019

Это потому, что вы помещаете обещания в массив синхронно . Promise.all работает с обещаниями, которые находятся в массиве к моменту его передачи.

Пример добавления обещания асинхронно:

 const promises = [Promise.resolve(1)];

 setTimeout(() => promises.push(Promise.resolve(2)), 0);

 Promise.all(promises).then(console.log); // [1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...