Waiting until async call is done to proceed in Node - node.js

I'm trying to build a bot cluster, and I'm having some trouble here.
I'd like to call the following function, called BuildABot.
http://pastebin.com/zwP7rZay
Now after this call is finished, I'd like to call requestItems, which takes in the steamOffers object as a parameter.
http://pastebin.com/jsJ4fhwG
However, the object is null, because the call hasn't finished.
Is there any way to halt the call until buildABot is done?

There are various ways to handle your requirement, I will mention 2 options while I am sure you can find more. You may find many more examples all over the web.
Option 1: Using a callback function -
Pass a callback function to the async function, When async function is finished it will call the callback func. This way the code in the callback func will be executed only when async call is over.
Related topic - how-to-write-asynchronous-functions-for-node-js
Option 2: If you have more complicated logic and you want to perform one part after another you can use the async waterfall.
Code example:
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
},
function(arg1, callback){
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
See async module site for more information.

Related

Node Async with functions

I'm trying to use Async module with 2 functions, here is the code. There's something wrong, the console.dir are working, but the last one in function(err, results) doesn't work. Can any one help me?
The last step that I want to do is render the oftArrayFullInfo and oftNextInfo
async.parallel({
one: function(callback){
auxFunctions.foofunc1(foo1, foo1, function(oftArrayFullInfo){
console.log("****** ASYNC 1 ARRAY");
console.dir(oftArrayFullInfo);
callback(oftArrayFullInfo);
});
},
two: function(callback){
auxFunctions.foofunc2(foo1, foo1, function(oftNextInfo){
console.log("****** ASYNC 2 ARRAY");
console.dir(oftNextInfo);
callback(oftNextInfo);
});
}
},
function(err, results){
console.log("****** RENDER 1");
console.dir(results.one);
console.log("****** RENDER 2")
console.dir(results.two);
//res.render('myView', {title: 'Job Info', oftArrayFullInfo}, {title: 'Next Jobs Info', oftNextInfo});
});
Your main issue is that you're not calling the callbacks correctly.
async callbacks, and asynchronous callbacks in Node.js in general, take two arguments: the first one is used to pass any errors (or null if there aren't any), the second one is used to pass the result.
You are calling them with only the first argument:
callback(oftArrayFullInfo);
This will make async think that the function has failed, which will cause results in the final callback to be undefined. When you subsequently try to access results.one, an error will be thrown.
To fix this, you should call the callbacks properly:
callback(null, oftArrayFullInfo)
callback(null, oftNextInfo)
And, as suggested already, you should uncomment the res.render().
Eventually, you should also make your auxilliary functions (auxFunctions.foofunc1 and auxFunctions.foofunc2) adhere to the same calling convention.
ok you did everything right except when u send data from re.render() to your templates you have to send in key,value pairs.so intead
res.render('myView', {title: 'Job Info', oftArrayFullInfo}, {title: 'Next Jobs Info', oftNextInfo});
you should use
res.render('myView', {title: 'Job Info', arrayFullInfo : oftArrayFullInfo}, {title: 'Next Jobs Info', nextInfo : oftNextInfo});
now you can access these values with the key names arrayFullInfo and nextInfo in your template

values getting overriden in callbacks inside callback in setInterval method node js

I have situation where i have an array of employees data and i need to process something parallel for every employee.To implement it and achieve the task i broke the things to chunks to four methods and every method has a callback calling each other and returning callback.I am using
async.eachSeries
to start the process for each element of the employee array.
In the last method i have to set the setInterval to perform same task if required response is not achieved,this interval is not cleared till the process of repeating task continues to 5 times(if desired value is not received 5 times,but cleared after 5th time).
Now,the problem happening is that data which i am processing inside setInterval is getting overriden by values of last employees.
So i am not able to keep track of process happening for all the employee Array elements and also the details of processing for last employee are getting mixed up.
In between the four methods which i am using for performing the task are carrying out the process of saving data to redis , MongoDB , Outside Api's giving response in callback.
Can anyone suggest better way of doing this and also i feel that the problem is happening because i am not returning any callback from SetInterval method().But since that method itself is an asynchronous method so i am unware about how to handle the situation.
EmployeeArray
async.eachSeries() used to process EmployeeArray
for each i have Four callBack Medhods .
async.eachSeries() {
Callback1(){
Callback2(){
Callback3(){
Callback4(){
SetInterval(No CallBack inside this from my side)
}
}
}
}
}
As per I know the async each function does parallel processing. Also u can use async waterfall to make your code more clean. Try something like this.
async.each(openFiles, function(file, callback1) {
async.waterfall([
function(callback) {
callback(null, 'one', 'two');
},
function(arg1, arg2, callback) {
// arg1 now equals 'one' and arg2 now equals 'two'
callback(null, 'three');
},
function(arg1, callback) {
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
callback1(err);
});
}, function(err){
//if you come here without error your data is processed
});

How to make use of async.applyEachSeries in node js?

Much appreciated if someone can give a more concrete example of how to use the async.applyEachSeries function.
async.applyEach([enableSearch, updateSchema], 'bucket', callback);
// partial application example:
async.each(
buckets,
async.applyEach([enableSearch, updateSchema]),
callback
);
This is from the async readme documentation, but I have no idea how to use it. What is the 'bucket', is it just a string being passed to somewhere?
async.applyEach([enableSearch, updateSchema], 'bucket', callback);
This calls enableSearch('bucket') and updateSearch('bucket') asynchronously with callbacks, and then calls callback() once they are both done.
// partial application example:
async.each(
buckets,
async.applyEach([enableSearch, updateSchema]),
callback
);
The async.applyEach() call returns a function that calls both enableSearch() and updateSchema() with its arguments when it is called. Since the first argument to async.each() should be an Array, I assume that buckets is an Array of Strings (as the first example involved passing one string to enableSearch() and updateSearch()). As a result, this could would call enableSearch() and updateSearch() with each String in the Array buckets (and then call callback()).
Here's a pretty clear example of async.applyEachSeries:
applyEachSeries(tasks, args..., [callback])
example:
function one(arg1, arg2, callback) {
// Do something
return callback();
}
function two(arg1, arg2, callback) {
// Do something
return callback();
}
async.applyEachSeries([one, two], 'argument 1', 'argument 2', function finalCallback(err) {
// This will run after one and two
});
Source: https://stackoverflow.com/a/35309495

Series flow with Async in NodeJS gets asynchrounously called

I need to call 3 functions in series x1() then x2() then x3(). But since x1 and x2 are time consuming operations x3 executes before them giving unexpected results. I have used the async library in NodeJS with the series method as below.
How can I solve this without using setTimeout for x3()
async.series([function(callback) { x1();callback(null, null);},
function(callback) { x2();callback(null, null);},
function(callback) {
x3();
callback(null, null); }],
function(err, results) { }
);
use recursive try catch..
a=true;
while(a){
try{
your work.....
a=false;
}catch(exp ){
a=true
}
}
You can use javascript's async nature to solve it. Here how it's done with callbacks. Call x3() instead of onMethodsDone().
Here, suppose x1() accepts an array. Forget it if you don't need any parameters. x3() gets the modified array from x2() which is also another time consuming function. setTimeout() is used to show the async behaviour since x1() and x2() are time consuming.
x1([1,2],function(results){
x2(results,onMethodsDone);
});
function onMethodsDone(results){
alert(results);
}
function x1(records,cb){
setTimeout(function (){
records.push(3,4,5);
cb(records); //parse updated records to callback
},2000);
}
function x2(records,cb){
setTimeout(function (){
records.push(6,7,8);
cb(records);
},2000);
}
javascripts Listeners or Promise/defers also can be used to handle it.
As the callback function had to be overloaded with different number of arguments the best option was to structure the method as follows
function callback(cbargs){
var arg1 = cbargs.cbarg1;
var arg2 = cbargs.cbarg2;
if(arg3!=null){
.....
}
}
function x1(arg1 , arg2, callback, cbargs){
.....
.....
callback(cbargs);
}
function x3(arg1 , arg2, callback, cbargs){
.....
.....
callback(cbargs);
}
x1(arg1, arg2,callback,{cbarg1, cbarg2});
x1(arg1, arg2,callback,{cbarg1, cbarg2, cbarg3});

Using node.js & async.js: series executing in the wrong order?

I am using express and async.js for a node application. I have this code in my app.js:
var resultObject = {};
app.get('/average', function(req, res) {
async.series([
function(callback) {
//This does some complex computations and updates the resultObject
routes.avg(req.query.url, resultObject);
console.log('1');
callback();
}
,
function(callback) {
res.send(resultObject);
console.log('2');
callback();
}
]);
});
The problem is that the res.send(...) fires before the complex computation in the first function finishes. Therefore, the object sent is empty. Is there some error in my code, or am I not using async.js correctly?
According to your comments, the problem is that your routes.avg method is asynchronous. This means that the method gets executed but doesn't block the program from continuing, which means that the 2nd closure in your series is being called almost immediately after the 1st one.
The problem isn't that the closures in the async.series call are being called out of order, it's that there's nothing that keeps your callback in closure 1 from being executed before routes.avg is finished.
To fix this, you could pass your callback into your routes.avg call, and edit the routes.avg method so that it calls the callback closure when all the calculation is done. That way, the 2nd closure in your series will not be executed until the callback passed to closure 1 is called by the routes.avg method.
If you don't have access to change the routes.avg method, then you have to find another way to detect when it's done it's work before you call the callback param passed to closure 1 from async.
Perhaps try something like this:
async.series([
function(callback) {
routes.avg(req.query.url, resultObject);
console.log('1');
callback();
},
function(callback) {
console.log('2');
callback();
}
],
function(err, results){
if(!err)
res.send(resultObject);
else
//do something here for error?
});

Resources