在 For 循环中使用 Promises .. 你如何知道它何时完成?

Using Promises In A For Loop.. How Do You Tell When It's Finished?

这是 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 循环中有一个获取承诺。根据长度 数组的 fetch 调用 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!!!

使用asyncawait:

(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

使用 Promise.all 创建一个新的 Promise,它会在所有提供的 Promise 都已解析后解析。

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!!!")
})

当您调用 fetch 时,它将 return 一个 Promise 对象,该对象将在响应可用时解析。但是,JavaScript 不会自动 对这个 Promise 对象做任何事情;你必须明确你想用它做什么。

promise 的基本用法通常是 "do something when this promise is resolved",它通过调用 Promise 对象上的 .then() 方法并传递回调函数来工作;您已经通过 .then(response => { console.log(response) }).

在您的代码中显示了这一点

为了知道多个 承诺何时完成,请使用静态Promise.all 函数。您需要通过将它们存储在数组中来跟踪您创建的所有 Promise 对象...

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

然后将该数组传递给Promise.all。这实际上将 return 一个新的 Promise 对象——当 所有 传递的承诺完成时,这个对象将解析:

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

那个 data 变量是什么?它将是 promises 数组中每个承诺解析的所有值的数组。因此,在此示例中,它将是每个 Response 对象。

(一个重要的 PS:当你做 promise.then(cb) 时,它会 return 一个新的承诺;这个新的承诺将在 cb 函数解析时解析,并且它的解析值将是任何 cb returned。这对于了解何时使用 Promise.all 非常有用,例如,如果您想获得 body 的响应;你会做 promises.push(fetch(...).then(res => res.body()));。)