Ниже приведен простой код Promise.all, но вывод сбивает с толку поведение Promise.all.

// A simple promise that resolves after a given time
const timeOut = (t) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Completed in ${t}`)
    }, t)
  })
}

// Resolving a normal promise.
timeOut(1000)
 .then(result => console.log(result)) // Completed in 1000

// Promise.all
Promise.all([timeOut(1000), timeOut(2000), timeOut(2000)])
 .then(result => console.log(result))

Может ли кто-нибудь объяснить мне, почему вывод не работает:

Completed in 1000
Completed in 2000
Completed in 2000
['Completed in 1000', 'Completed in 2000', 'Completed in 2000'] 

Вот что я получаю:

Completed in 1000
['Completed in 1000', 'Completed in 2000', 'Completed in 2000']
0
Rex 30 Май 2023 в 22:00
Я считаю, что внутренние операторы журнала не вызываются из-за оптимизации вызова Promise.all. Каждая из функций обещания then() не вызывается.
 – 
Mr. Polywhirl
30 Май 2023 в 22:07

3 ответа

Согласно документации MDN

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

Таким образом, вы получаете один single промис, значение которого представляет собой массив изначально переданных (теперь разрешенных) промисов.

Вы добавили .then() только к одному промису:

// Resolving a normal promise.
timeOut(1000)
 .then(result => console.log(result)) // Completed in 1000

Следовательно, соответствующее сообщение было напечатано.

Отвечает ли это на ваш вопрос?

0
UmbQbify 30 Май 2023 в 22:10

Ваш вывод правильный - Promise.all возвращает обещание массива с результатами разрешенных обещаний в аргументе массива. Таким образом, в result => console.log(result) вы получаете массив результатов всех ваших промисов и печатаете его.

0
Alexander Nenashev 30 Май 2023 в 22:11

Вам нужно сопоставить промисы и вызвать их обработчики разрешения then().

// A simple promise that resolves after a given time
const timeOut = (t) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Completed in ${t}`)
    }, t)
  })
}

// Resolving a normal promise.
timeOut(1000)
 .then(result => console.log(result)) // Completed in 1000

// Promise.all
Promise
  .all([timeOut(1000), timeOut(2000), timeOut(2000)]
    .map(p => p.then(msg => {
      console.log(msg) // map and call `then()` which receives the message
      return msg // make sure you return the original message
    })))
 .then(result => console.log(result))
0
Mr. Polywhirl 30 Май 2023 в 22:11