Использование обещаний в цикле ... Как узнать, когда он закончится? - PullRequest
0 голосов
/ 25 февраля 2019

Вот jsfiddle: https://jsfiddle.net/8ocdupar/

var arr = [0,1,2,3,4,5];

for (var i = 0; i < arr.length; i++) {
    fetch("https://jsonplaceholder.typicode.com/todos/1")
    .then(response => {
        console.log(response);
    });
}
console.log("DONE!!!")

В этом простом примере у меня есть обещание извлечения внутри цикла for.В зависимости от длины массива он будет вызывать выборку 6 раз.У меня вопрос, как я могу узнать, когда это будет сделано?

Я не очень хорошо понимаю асинхронное поведение.Мне кажется, я хочу, чтобы этот пример действительно вел себя синхронно.

Когда этот цикл завершен и все вызовы сделаны, я просто хочу записать, что это сделано.

Вот чтопример в настоящее время выводит:

DONE!!!
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}

И это то, что я хочу, чтобы он вывел:

(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
(index):39 Response {type: "cors", url: "https://jsonplaceholder.typicode.com/todos/1", redirected: false, 
status: 200, ok: true, …}
DONE!!!

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

Используйте Promise.all для создания нового Обещания, которое разрешается после разрешения всех предоставленных Обещаний.

let arr = [0, 1, 2, 3, 4, 5]
let promises = []

for (let i = 0; i < arr.length; i++) {
  promises.push(
    window
      .fetch("https://jsonplaceholder.typicode.com/todos/1")
      .then(response => {
        console.log(response)
      })
  )
}

Promise.all(promises).then(() => {
  console.log("DONE!!!")
})
0 голосов
/ 25 февраля 2019

Когда вы вызываете fetch, он вернет объект Promise, который разрешится, когда ответ станет доступен.Однако JavaScript не автоматически ничего не делает с этим объектом Promise;Вы должны четко указать, что вы хотите с ним сделать.

Основное использование обещания обычно заключается в том, чтобы «сделать что-то, когда это обещание разрешено», что работает путем вызова метода .then() в обещании.объект с переданной функцией обратного вызова;вы уже показываете это в своем коде, выполняя .then(response => { console.log(response) }).

Чтобы узнать, когда несколько обещаний закончились, используйте статическую функцию Promise.all.Вам нужно будет отслеживать все объекты Promise, которые вы создаете, сохраняя их в массиве ...

const promises = [];
for (/* each item in the array */) {
    promises.push(fetch(...));
}

Затем передавайте этот массив в Promise.all.Это на самом деле вернет новый объект Promise - этот разрешит, когда all выполненные пропущенные обещания:

Promise.all(promises).then(data => {
    ...
});

Что это за переменная data?Это будет массив всех значений, разрешенных каждым обещанием в массиве promises.Таким образом, в этом примере это будет каждый объект Response.

(Важный PS: когда вы выполните promise.then(cb), он вернет новое обещание; это новое обещание разрешится, когда разрешится функция cbи его разрешенное значение будет равно cb. Это очень полезно знать, когда вы используете Promise.all, например, если вы хотите получить тело ответа; вы 'буду делать promises.push(fetch(...).then(res => res.body()));.)

0 голосов
/ 25 февраля 2019

Используйте async и await:

(async function () {
  var arr = [0,1,2,3,4,5];
  for (var i = 0; i < arr.length; i++) {
    let response = await fetch("https://jsonplaceholder.typicode.com/todos/1")
    let o = await response.json(); // <-- you'll want this too...
    console.log(o);
  }
  console.log("DONE!!!")
})(); // <-- execute it
...