在For循环中使用Promises。如何确定何时完成?

时间:2019-02-24 22:01:22

标签: javascript ecmascript-6 promise fetch es6-promise

这是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 :(得分:3)

使用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

答案 1 :(得分:2)

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

答案 2 :(得分:0)

调用fetch时,它将返回Promise对象,该对象将在响应可用时进行解析。但是,JavaScript不会对此Promise对象自动执行任何操作。您必须明确要使用它。

一个promise的基本用法通常是“在解决此promise时做一些事情”,这是通过在Promise对象上调用.then()方法并传递回调函数来实现的;您已经通过执行.then(response => { console.log(response) })在代码中显示了这一点。

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

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

然后将该数组传递到Promise.all。实际上,这将返回一个新的Promise对象-当完成所有 承诺时,该对象将解决:

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

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

(重要的PS:执行promise.then(cb)时,它将返回一个新的Promise;此新Promise将在cb函数解析时解析,并且其解析的值将为{{1} }返回。这对于知道何时使用cb很有用,例如,如果您想获取响应的 body ;您可以进行Promise.all