How to run a function after completing the async function in node.js?

I want to run the code after forEach.

myPosts.forEach(function(post) {
    getPostAuthor(post.authorID, function(postAuthor) {
        post.author = postAuthor;
    }
});

res.render('index', {
    posts: myPosts
});
res.end();

in the code above the first res.render starts, and after that forEach fills post.author

+4
source share
6 answers

Rather go to Promises than iterate with forEach, then use Promise.all:

Promise.all(
 myPosts.map(function(post) {
  return new Promise(function(res){
   getPostAuthor(post.authorID, function(postAuthor) {
      post.author = postAuthor;
      res(postAuthor);
   });
  });
})
).then(function(authors){

  res.render('index', {
     posts: myPosts
   });
  res.end();

});
+4
source

You can create an array of promises, and then listen to all the improvements with Promise.all.

const promises = [];

myPosts.forEach(function(post) {
    const promise = new Promise((resolve) => {
      getPostAuthor(post.authorID, function(postAuthor) {
          post.author = postAuthor;
          resolve(); // complete the current promise
      }
    });

    promises.push(promise);
});

Promise.all(promises).then(() => {
  res.render('index', {
    posts: myPosts
  });
  res.end();
});
+2
source

, / Promise .

:

var numComplete = 0;
var done = function() {
    if(numComplete >= myPosts.length) {
        // Code to run once finished
    }
};

myPosts.forEach(function(post) {
    getPostAuthor(post.authorID, function(postAuthor) {
        post.author = postAuthor;
        numComplete++;
        done();
    }
});
0

lib, ​​ Async.

:

import each from 'async/each';

var elements = [1, 2, 3, 4, 5, 6];

each(elements, function(el, next) {
    console.log('Processing element ' + el);
    callAsyncFunction(next); //your async function should accept a callback
}, function(err){
    //this is your ending function. It'll be called after all elements have been processed
    if( err ) {
        console.log('A file failed to process');
    } else {
        console.log('Async processing is finished.');
    }
});

:

each(myPosts, function(post, next) {
    getPostAuthor(post.authorID, function(postAuthor) {
        post.author = postAuthor;
        next()
    });
}, function(err) {
    if (!err) {
        res.render('index', {
            posts: myPosts
        });
        res.end();
    }
});
0

async/await for loop.

const sleep = timeout => new Promise(resolve => setTimeout(() => resolve(), timeout));
const myPosts = [1,2,3];

const fetchPosts = async () => {
  for (let post_id of myPosts) {
    await sleep(1000); // simulate fetch post
    console.log('post:', post_id);
  }

  console.log('done!');
};

fetchPosts();
Run codeHide result
0
source

use async.eachOf to iterate over the array and apply the async function:

 async.eachOf(myPosts, function(post, it, callback){

    // apply async function on each element
    getPostAuthor(post.authorID, function(postAuthor) {
        post.author = postAuthor;
        return callback();
    });

 }, function(err){
    // final callback when flow is finished
    res.render('index', {
         posts: myPosts
    });
    return res.end();
 });

See asynchronous documentation: https://caolan.imtqy.com/async/docs.html

0
source

Source: https://habr.com/ru/post/1683263/


All Articles