user97811 user97811 - 1 month ago 7
Node.js Question

Node.js - Execute functions one by one

I am trying to run these functions one by one, after it will execute first function move to second one and so on .. now it will render both functions at the same time, it is taking so much memory when there are over 3000 functions.

webshot('google.com', 'google.jpeg', options, function(err) {});
webshot('yahoo.com', 'yahoo.jpeg', options, function(err) {});

Answer

That last argument to each of those is called a "callback;" it gets called when the work has been finished. So if you want to do these one at a time, put the call to the next one inside the callback of the previous one:

webshot('google.com', 'google.jpeg', options, function(err) {
    webshot('yahoo.com', 'yahoo.jpeg', options, function(err) {});
});

Of course, if you have a bunch of these (you mentioned 3000!), you're not just going to nest them like that. I would probably create an array of the arguments you want to pass them, and then use a callback loop:

function process(list, callback) {
    var index = 0;

    doOne();

    function doOne() {
        var entry = list[index++];
        webshot(entry.domain, entry.img, entry.options, function(err) {
            // ...error handling, etc...
            if (index < list.length) {
                doOne();
            } else {
                callback();
            }
        });
    }
}
var webshots = [
    {domain: 'google.com', img: 'google.jpeg', options: options},
    {domain: 'yahoo.com', img: 'yahoo.jpeg', options: options},
    // ...
];
process(webshots, function() {
    // All done
});

Side note: This would be a bit cleaner with Promises. There are various libraries that will promise-ify Node-style callback APIs (like webshot's), you might look at doing that.

If you did, you could handle those promises like this:

var webshots = [
    {domain: 'google.com', img: 'google.jpeg', options: options},
    {domain: 'yahoo.com', img: 'yahoo.jpeg', options: options},
    // ...
];
allDone = webshots.reduce(function(p, entry) {
    return p.then(function() {
        return promisifiedWebshot(entry.domain, entry.img, entry.options);
    });
}, Promise.resolve());
allDone.then(function() {
           // All done
       })
       .catch(function() {
           // Handle error
       });