简体   繁体   中英

Node.js wait until async functions are complete, then continue with the rest of the code

In my code I have 2 for loops executing one async function (it's the same function in both loops), but the code, after these 2 loops, has to wait until the execution of them, before it runs. This is my code:

for(var a = 0; a < videoIds.length; a++){
  if(videoIds){
    findVideo(videoIds[a], function(thumbnailPath, videoName){ // findVideo is the async function
      // it returns 2 values, thumbnailPath and videoName
      videoNames[a] = videoName; // and then these 2 values are written in the arrays
      thumbnaildPaths[a] = thumbnailPath;
      console.log('1');
    });
  }
}

// then the above code runs one more time but with different values, so I won't include it here (it's the same thing)
enter code here
console.log('3');
// the rest of the code
// writes the values from the loops to the database so I can't run it many times 

If I run the code, I see 3 (from the console.log function) before I see 1. But as I stated above I have to wait for the loop to end before moving on. The findVideo() function just contains a Video.find({}) method provided by mongoose, and then returns the values thumbnailPath and videoName. What I need to do is wait for the 2 loops to end and then continue, but I can't have the rest of the code inside the loops for obvious reasons! Is there any way to fix this? Thank you!

You can use callbacks but I prefer promises because they are elegant.

Make use of Promise.all() https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

function getVideo(id){
  return new Promise(function(resolve, reject){
    findVideo(id, function(thumbnailPath, videoName){
      resolve({
        name: videoName,
      thumbnail: thumbnailPath
      });
    });
  });
}

var promises = videoIds.map(function(videoId){
  return getVideo(videoId);
});

//callback in then section will be executed will all promises will be resolved 
//and data from all promises will be passed to then callback in form ao array.
Promise.all(promises).then(function(data){
  console.log(data);
});

// Same for other list of tasks.

Simplest solution is to just use a callback. just wrap your loops in a function and do something like this.

function findVid(callback) {
    for(var a = 0; a < videoIds.length; a++){
        if(videoIds){
            findVideo(videoIds[a], function(thumbnailPath, videoName){ // findVideo is the async function
                // it returns 2 values, thumbnailPath and videoName
                videoNames[a] = videoName; // and then these 2 values are written in the arrays
                thumbnaildPaths[a] = thumbnailPath;
                console.log('1');
                if (callback) callback(); //This will be called once it has returned
            });
        }
    }
}
findVid(function(){ 
    //this will be run after findVid is finished.
    console.log('3');
    // Rest of your code here.
});

You could as well use Promise style instead of callback, however both with work. To understand a bit more about callbacks and promised, I found a good article that will explain everything in more detail: http://sporto.github.io/blog/2012/12/09/callbacks-listeners-promises/

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