如何在 JavaScript 中使用异步循环?

问题描述 投票:0回答:3

如何编写循环并向服务器发送请求,以便在收到上一个请求的响应后执行下一个请求?

我希望请求按顺序发送,结果按顺序显示:

for (item of [1,2,3]){
  fetch(`http://test.com/users/${item}`).then((res)=>{
     console.log(res.id) // I want the next request, to be send after received this reponse
  }) 
}
javascript asynchronous
3个回答
1
投票

您应该使用

.then()
,而不是使用
await
,它在
for
while
do..while
循环中工作(另外,您应该将
fetch
调用包装在
try...catch
中) :

function fakeFetch(url) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ id: url })
    }, 1000)
  })
}

async function fetchItems() {
  for (let item of [1,2,3]){
    console.log(`Fetching ${ item }...`)
    
    try {
      const res = await fakeFetch(`http://test.com/users/${ item }`)

      console.log(res.id)
    } catch (err) {
      console.log(`Item ${ item } error:`, err)
    }
  }
}

fetchItems()

请注意,这不适用于需要回调的数组方法,例如

forEach
map
reduce
filter

这种方法的缺点是它比并行解决承诺(请求)需要更长的时间,因为您需要等待一个解决后再发出下一个请求。相反,您可能需要考虑使用

Promise.allSettled()
:

function fakeFetch(url) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({ id: url })
    }, 1000)
  })
}

async function fetchItems() {
  const promises = [1,2,3].map((item) => {
    console.log(`Fetching ${ item }...`)
    
    return fakeFetch(`http://test.com/users/${ item }`)  
  })
  
  const items = await Promise.allSettled(promises)
  
  console.log(items)
}

fetchItems()


1
投票

使用等待标志。所以等待 fetch(...) 应该做到这一点

async function example() {
  for (item of [1, 2, 3]) {
    let res = await fetch(`http://test.com/users/${item}`);
    console.log(res.id); // I want the next request, to be send after received this reponse
  }
}


-2
投票

要按顺序发送请求并在发送下一个请求之前等待每个请求的响应,可以使用

async/await
语法。通过使用
async/await
,您可以使异步代码看起来更加同步,并且它允许您暂停函数的执行,直到异步操作完成。

以下是如何修改代码来实现此目的:

async function fetchUsersSequentially() {
  for (const item of [1, 2, 3]) {
    try {
      const response = await fetch(`http://test.com/users/${item}`);
      const data = await response.json();
      console.log(data.id);
    } catch (error) {
      console.error(`Error fetching user ${item}:`, error);
    }
  }
}

fetchUsersSequentially();

在上面的代码中,我们定义了一个

async
函数
fetchUsersSequentially()
。在循环内部,我们使用
await
等待接收响应,然后使用
response.json()
解析响应。这样,只有在前一个请求处理完毕后,才会发送下一个请求。

请记住,使用

async/await
时,使用 try-catch 块处理错误非常重要。如果任何请求失败,catch 块将处理错误,并且循环将继续到下一次迭代。

现在,当您调用

fetchUsersSequentially()
时,请求将按顺序发送,响应将按顺序记录。

© www.soinside.com 2019 - 2024. All rights reserved.