简体   繁体   中英

How to make async/wait inside of for loop?

I'm using async await inside of for loop as below.

for (let i = 0; i < result.length; i += 1) {
  try{
    const client = await axios.get(
      `${process.env.user}/client/${result[i].id}`
    );
  } catch(error){
    console.log(error)
  }
    if (client.data.success === true) {
      result[i].Name = rider.data.client.Name;
      result[i].PhoneNumber = rider.data.client.Number;
    }
  }

But I want to make this using 'new Promise' and 'promiss.all' to make it asynclously.
But I don'k know how to make this correctly doing error handle well.
Could you recommend some advice for this? Thank you for reading it.

Try this

var promises = result.map(r => axios.get(`${process.env.user}/client/${r.id}`);

Promise.all(promises).then(function(values) {
   console.log('All promises done');
});

The idea is that if you are awaiting something, that is promise, you can await it, or call it to get promise

Example:

function Foo()
{
    return new Promise(...); // Promise of int for example
}

you can do

var p = Foo(); //you will get promise

Or

var v = await Foo(); // you will get int value when promise resolved

This is how you do it with async/await + Promise.all :

const myResult = await Promise.all(result.map(({ id }) => {
  return axios.get(`${process.env.user}/client/${id}`);
}));

// deal with the result of those requests
const parsed = myResult.map(data => /* your code here */);

Here is an example using Array.map to call your function along with Promise.all . I wrapped the axios request in a function so if one of your request fails, it wont stop every other requests. If you don't mind stopping when you got an issue, look at others answers to your question.

 function fakeRequest() { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ data: { success: true, client: { Name: 'Todd', Number: 5, }, }, }); }, 300); }); } (async() => { const result = [{}, {}, {}]; await Promise.all(result.map(async(x, xi) => { try { const client = await fakeRequest(); if (client.data.success === true) { result[xi].Name = client.data.client.Name; result[xi].PhoneNumber = client.data.client.Number; } } catch (err) { console.log(err) } })); console.log(result); })();

This can be a basic solution, i think

let playList = []
for (let i = 0; i < result.length; i += 1) {
    playList.push(axios.get(
        `${process.env.user}/client/${result[i].id}`
    ).then(res => {
        if (res.data.success === true) {
            result[i].Name = rider.data.client.Name;
            result[i].PhoneNumber = rider.data.client.Number;
        }
    }).catch(ex => console.log(ex)));
}
await Promise.all(playList)

This can also be done by using a foreach loop. The for/foreach loop can be simplified by using a map function. Js map function is equivalent of c# select linq function. The fat arrow in js map function is not bound to return a value unlike c# select inner function which must return a value.

await Promise.all(result.map(async r => {
        let client;
        try {
            client = await axios.get(`${process.env.user}/client/${r.id}`);
        } catch (error) {
            console.log(error)
        }
        if (client.data.success === true) {
            r.Name = rider.data.client.Name;
            r.PhoneNumber = rider.data.client.Number;
        }
    }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM