How does nesting async functions inside the final callback work? - javascript

var foo = function (callback_foo) {
async.series([func1, func2, func3], function (err) {
if (err) {
return callback_foo(err)
}
async.series([func4, func5], function(err){
if (err) {
return callback_foo(err)
}
return callback_foo(); //1
});
return callback_foo(); //2
});
}
do I need to return callback_foo() two times? the first callback_foo() is to tell async.series func4, fun5 is done. And the second callback_foo() is to tell the outer async.series func1,func2, func3 are done. is that right?

you could do it like below.
var foo = function (callback_foo) {
async.series([
func1(callback) {
//func1 processing
callback(); //this will call func2 after func1 is done
},
func2(callback) {
//func2 processing
callback(); //this will call func 3 after func 2 is done
},
func3(callback) {
//do your func3 processing here,then call async.series for 4 and 5.
async.series([
func4(callback) {
//do func 4 processing here
callback(); //This will call func5 after func4 is done
},
func5(callback) {
//do func5 processing here
callback(); //this will call the final callback of the nested async.series()
}], function (err) {
//this is the final callback of the nested(2nd) async.series call
callback(); //this is the iterator callback of func3,this will now call the final callback of the original async.series
});
}], function (err) {
//final callback after all the functions are executed.
return callback_foo();//call your foo's callback.
});
}
Note:callback used in func1,2,3,4,5 need not be defined,its async.series's iterator callback,thats helps us to move to the next function.
However i don't see the point of nested async.series calls.you could do it with 1 async.series call.
var foo = function (callback_foo) {
async.series([func1, func2, func3,func4,func5], function (err) {
if (err) {
return callback_foo(err)
}
});
};

Related

Wait for inner functions to wait and execute then proceed execution

I am executing a cloud function which is written in nodeJS.Here the function triggers when a data from the external source comes in and in this function, I have to call and check DB at the particular table but it takes more than 5 seconds and before the execution of my getDataFromDb function my main function completed execution. Plus there is a function called updateItems(postdate); and it executes if I cannot find data in my DB when triggering getDataFromDb
I tried async await but I am not sure where I am doing wrong. my function always ends first before my DB operation ends.
exports.handler = (event, context) => {
//here i am making data ready for DB and checking for the record if that is present in db
getDataFromDb(uniqueArray);
function getDataFromDb(uniqueArray) {
var params = {
// params for get reques
}
//db get operation
db.get(params, function (err, data) {
//takes time here
if (err) {
console.log(err); // an error occurred
}
else {
//another DB operation updateItems(postdata);
//takes time here
}
else {
console.log("first run for db")
//another DB operation updateItems(postdata);
//takes time here
}
}
});
}
});
console.log("main function ended")
};
the expected result should wait for the inner function to execute then end the main function but actually, the main function ends first then DB calling function ends
Though this can be achieved through callbacks, converting it to promise chain makes it easy, as execution of inner function depends on outer function, it's better to chain promises i.e. return Promise in the call back of first function, to execute them serially.
exports.handler = (event, context) => {
getDataFromDb(uniqueArray).then(success => {
console.log('Done')
})
.catch(err => {
console.log('handle get or post err here');
});
function getDataFromDb(uniqueArray) {
var params = {};
return new Promise((resolve, reject) => {
db.get(params, (err, data) => {
if (err) {
return reject(err); // an error occurred
} else {
return resolve(data);
}
});
}).then(success => updateItems(data))
}
});

Cannot access db result in Nodejs, it always returns null

var robject=[];
async.waterfall([
function (callback) {
for(var i in serial){
Router.find({},{r_serial_no:serial[i]},function (err,routerData) {
robject = robject.concat(routerData);
});
}
console.log('Robject= '+robject); //THIS RETURNS NULL
callback(null, robject);
},
function (blogs, callback) {
res.render('index', {dispatched_data:dispatched_data });
callback(null, 'Ended..' );
}
], function (err, result) {
console.log(result);
});
this is my waterfall model, here i need to access the robject from schema.find method to outside of that method. but it always return null..
how to access that??
You have the syntax error:
for(var i in serial){
Router.find({},{r_serial_no: i},function (err,routerData) {
robject = robject.concat(routerData);
});
}
the "for" loop defines "i" as next item in the array each iteration
The problem I see here is in for...in loop. Your callback will be fired even if your process i.e. Router.find is not completed. You can try below code, It might help.
Unlike your serial object please create a array called serials.
var robject=[];
async.waterfall([
function (callback) {
async.each(serials,
function(serial, localCb){
Router.find({},{r_serial_no:serial},function (err,routerData) {
robject = robject.concat(routerData);
localCb()
});
},
function(err){
console.log('Robject= '+robject);
callback(null, robject);
}
);
},
function (blogs, callback) {
res.render('index', {dispatched_data:dispatched_data });
callback(null, 'Ended..' );
}
], function (err, result) {
console.log(result);
});

Calling a parameterized callback function within a mongoose async callback function becomes 'undefined'

I am having a weird problem with calling a callback inside another callback from mongoose.
Setup : MEAN Stack.
myFunc = function (cb) {
var projection = {
'_id': 0,
'var1': 1,
'var2': 1
}
var order = {
'var1': 1
}
User.find({})
.select(projection).sort(order)
.exec(function(err, docs){
if(err){
console.log(err);
cb(err,docs);
} else {
console.log(docs);
cb(err,docs);
}
});
};
going to the lines where cb(err,docs) will result in
"ReferenceError: cb is not defined"
the weird part is
I have functions with even deeper nested callbacks that can invoke the "cb" normaly.
myFunc = function(cb){
model1.count({var1:'test'}, function (err, count) {
if(count) {
model2.findOne({dat1:'hoho'}, function (err, doc){
if (err) {
console.error(err);
cb(err,doc);
} else {
cb(err,doc);
}
});
} else {
cb({message: "No items found"}, null);
}
})
}
The code above will be invoked like so...
function init(something){
myfunc(function(err, doc) {
if (err){
console.log(err.message);
} else {
//do something about doc
}
});
}
ugh, it seems that the calling function did not properly follow the rules.
it called
myFunc(json, function(err,doc){
//do something
})
wrong param count...

Call object property from within a callback

I have an async.series() calling a function from another javascript object:
main.js
var object1 = require('./object1');
var object1 = require('./object2');
async.series([
object1.myFunction1,
object2.anotherFunction
]);
object1.js
module.exports = {
function1: function(callback){
async.each(someArray, function(item, cb) {
function2(item);
}, function(err){
if(err) return callback(err);
callback();
});
},
function2:function(item, callback){
//Do something
}
};
This code does not work because function2 is undefined inside the callback. I tried to put
var refToFunction2 = this.function2
at the beginning of function1. It works if we call directly function1, but here function1 is called by async and for some reasons: this = undefined.
Is there a clean way to do that ?
You could setup your object1.js file in the following way:
var async = require('async');
function function1(callback){
async.each(someArray, function(item, cb) {
function2(item);
}, function(err){
if(err) return callback(err);
callback();
});
}
function function2(item, callback){
//Do something
}
module.exports.function1 = function1;
module.exports.function2 = function2;
You should now notice that function1 and function2 are defined globally in the file. This means they can be called inside of each other freely.

How to use setTimeout in Node.JS within a synchronous loop?

The goal I'm trying to achieve is a client that constantly sends out data in timed intervals. I need it to run indefinitely. Basically a simulator/test type client.
I'm having issues with setTimeout since it is an asynchronous function that is called within a synchronous loop. So the result is that all the entries from the data.json file are outputted at the same time.
But what i'm looking for is:
output data
wait 10s
output data
wait 10s
...
app.js:
var async = require('async');
var jsonfile = require('./data.json');
function sendDataAndWait (data) {
setTimeout(function() {
console.log(data);
//other code
}, 10000);
}
// I want this to run indefinitely, hence the async.whilst
async.whilst(
function () { return true; },
function (callback) {
async.eachSeries(jsonfile.data, function (item, callback) {
sendDataAndWait(item);
callback();
}), function(err) {};
setTimeout(callback, 30000);
},
function(err) {console.log('execution finished');}
);
You should pass the callback function:
function sendDataAndWait (data, callback) {
setTimeout(function() {
console.log(data);
callback();
//other code
}, 10000);
}
// I want this to run indefinitely, hence the async.whilst
async.whilst(
function () { return true; },
function (callback) {
async.eachSeries(jsonfile.data, function (item, callback) {
sendDataAndWait(item, callback);
}), function(err) {};
// setTimeout(callback, 30000);
},
function(err) {console.log('execution finished');}
);

Categories