1

I know Js is async but how to prevent my callback from returning an empty array ? Here is my code :

function getPicturesArray(nbr,callback){
    var avatarArr = [];
    for(var i =0; i<nbr ; ++i){
        request("https://randomuser.me/api/",{json: true},(err,response,body)=> {
            avatarArr.push(body.results[0].picture.large);
        });
    }
    callback(avatarArr);
}

getPicturesArray(12, (e)=>{
    console.log(e);
});

console.log('here');

And the sout is: [] here

2 Answers2

0

Don`t use callbacks. Use Promises or async/await.

  getUserPic = async () => {
    const url = 'https://randomuser.me/api/'
    const response = await fetch(url)
    const users = await response.json()

    return users.results[0].picture.large
  }
  ;(async () => {
    const userAvatars = []
    for (let i = 0; i < 12; i++) {
      userAvatars.push(await getUserPic())
    }
    console.log(userAvatars)
  })()

Also try to use this. In this case I advice you to use Set instead of Array to exclude duplicate items.

  getUserPic = async () => {
    const url = 'https://randomuser.me/api/'
    const response = await fetch(url)
    const users = await response.json()

    return users.results[0].picture.large
  }

  getMultipleUserPics = async limit => {
    const userAvatars = new Set()
    while (userAvatars.size != limit) {
      userAvatars.add(await getUserPic())
    }

    return userAvatars
  }

  ;(async () => {
    const userPics = await getMultipleUserPics(5)
    console.log(userPics)
  })()
gusarov.f
  • 26
  • 2
0

I'm mocking the calls with a public service for demonstration purposes, but the key point here is the asynchronous nature of HTTP requests.

When you invoke callback(avatarArr);, your for loop IS done but the (in this case 12) requests you sent are not, so avatarArr does not have any items yet.

Notice async before function getPicturesArray, and await before fetch

await tells the execution to wait for the fetch call to finish

You MUST check out async/await.

async function getPicturesArray(nbr,callback){
    var avatarArr = [];
    console.log('loading...');
    for(var i =0; i<nbr ; ++i){
      const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${i+1}`);
      const json = await response.json();
      avatarArr.push(json.title);  
    }
    console.log('done loading...');
    callback(avatarArr);
}

getPicturesArray(12, (e)=>{
    console.log(e);
});

console.log('see how this is executed before done loading...');
Scaramouche
  • 3,188
  • 2
  • 20
  • 46