Reputation: 3
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) {});
Upvotes: 0
Views: 1960
Reputation: 1075547
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
});
Upvotes: 4
Reputation: 7873
You can use a control flow library like async:
'use strict';
const async = require('async');
async.series([
(callback) => {
webshot('google.com', 'google.jpeg', options, callback);
},
(callback) => {
webshot('yahoo.com', 'yahoo.jpeg', options, callback);
}
], (error) => {
if(error) {
console.log('Error: ' + error);
}
});
There are also utilities function like map
, each
, eachOf
to allow you to directly iterate throught your list of url and apply to the call:
'use strict';
const async = require('async'),
urls = [
{url: 'google.com', img: 'google.jpeg'},
{url: 'yahoo.com', img: 'yahoo.jpeg'}
];
async.map(urls, (url, callback) => {
webshot(url.url, url.img, options, callback);
//I presumed webshot call the callback like callback(error, result)
}, (error, webshots) => {
//If a error occured, async will skip there and error will be set
//Else, webshots will be a array of all the results
});
Upvotes: 1