I have two class functions in nodejs and I want to call both synchronously both one after another.
var questionData = questionModelObj.getQuestionbyId(req.params.id);
var answerData = answerModelObj.getAnsByQuesId(req.params.id);
Here questionModelObj take time to execute and it calls answerModelObj without completing questionModelObj. It results answerData overwrites the questionData.
Please suggest how to call these two functions one after another(synchronous) and explain.
One option is to execute the second function as a callback to the first. This is pretty standard for Javascript.
// Declare variable to hold response
var answerData;
var questionData = questionModelObj.getQuestionbyId(req.params.id, function() {
// This is the callback function
answerData = answerModelObj.getAnsByQuesId(req.params.id);
}
The function signature of getQuestionbyId would then need to take in 2 parameters, the second being a function to be called later on:
questionModelObj.getQuestionbyId = function(id, callback) {
// Do things with the id
callback();
}
The callback function is then called after getQuestionbyId is done.
Related
I'm unable to get the values in meals object although i have create new object at the top can any one tell which is the best procedure access variable inside callback function
var meals = new Object();
passObj.data = _.map(passObj.data, (x)=> {
x.mealImageUrl = !_.isNull(x.image_url) ? `${config.image_path}${x.image_url}` : x.image;
dbHelpder.query(`select * from meals where meal_category = ${x.category_id}`,(error,result)=>{
meals = x.result;
passObj.total = 555
});
return x;
});
You need to use callback again inside the callback function. :)
You are doing something asynchronous, it means, there are no sequence codes. (At least, I keep this in my mind, don't know how others think about this.) So, the code should be:
function somehow(callback) { // you get the result from callback
var meals = new Object();
passObj.data = _.map(passObj.data, (x)=> {
dbHelpder.query(`select * from meals where meal_category = ${x.category_id}`,(error,result)=>{
meals = x.result;
passObj.total = 555;
callback(meals); // Here you get the result
});
}
return x;
}
So, when you are going to use this function, it should be
function afterMeals(resultMeals) {
// do something on the meals
}
somehow(afterMeals);
Use some other technology can make it a bit clear (like promise), but you can not avoid callback actually.
First of all, I cannot see what passObj exactly is, apparently it is defined elsewhere.
Secondly, callback functions don't function the way you seem to think they do. Typically one reason to use them is to implement asynchronous calls, so returning a value is not of use.
The idea is as follows. Usually you have a call like this:
var myFunc1 = function(){
return 42;
}
var x = myFunc1();
myFunc2(x);
However when myFunc1 is an asynchronous call returning a value is impossible without using some sort of promise, which is a topic on its own. So if myFunc1 was an asynchronous call and the 42 was returned e.g. by a server, then just returning a value caused the value to be null, because the return value is not calculated and received yet, when you arrive at return.
This is a reason for callbacks to be introduced. They work in a way, that allows for asynchronous calls and proceeding the way you want to after the call has finished. To show on the example above:
var myFunc1 = function( myFunc2, params ){
// do async stuff here, then call the callback function from myFunc1
...
myFunc2(x);
}
So the asynchronous function doesn't return anything. It makes the calls or calculations it needs to make and when those are done (in the example that is when x has been declared and assigned a value) myFunc2, which is the callback function in our example, is called directly from the asynchronous function.
Long story short - do what you need to do with x directly inside the callback function.
I want to execute 4 functions in order. Each functions is of the below format. Like create update delete and display. I want to call the display function after completing the other 3 functions. I tried promise method but without any db call it is working in order.When a mongoose call is happening, the order is getting changed.
function createProjects(req) {
var projects = req.body.created;
projects.forEach(function (project) {
var newProject = new ProjectSchema(project);
newProject.save(function (error, object) {
if (error) {
console.log(error)
}
console.log(object)
});
});
}
How this issue can be resolved?
You need the code to wait until one promise completes before starting the next one, using something like bluebird.each, the async library, or a next callback queue. The first part of that sentence may sound like a duh sort of thing, but in node.js .save will always return immediately, regardless of when the callback is executed (making it less obvious in the code).
Here's an example with bluebird.each I tried to stick to the code style you are using in your example code.
var Promise = require('bluebird');
function createProjects(req) {
var projects = req.body.created;
return Promise.each(projects, function (project) {
return new ProjectSchema(project).save();
});
}
I am trying to test the following code:
var archive = function(callback){
call to this.archive() here...
}
var map = function(callback){
call to this.map() here...
}
async.parallel([map, archive], function(error){
handle errors here...
})
I am testing that the handle errors functionality is working by stubbing the archive and map functions so that one of them returns an error:
var mapStub = sinon.stub(MyClass.prototype, 'map').yields("mock error",null );
var archiveStub = sinon.stub(MyClass.prototype, 'archive').yields(null,null );
The problem I am having is that the archiveStub does not seem to be being used, as I am getting errors from a function which is called by that function (which would be expected if that function was called as I have not initialised variables for this test).
I have another test, where the archive function returns an error instead of the map function, and this test passes without seeming to call either of the stubbed methods instead of the stubs.
var mapStub = sinon.stub(MyClass.prototype, 'map').yields(null,null );
var archiveStub = sinon.stub(MyClass.prototype, 'archive').yields("mock error",null );
You want to use yieldsAsync instead of yields, otherwise the error is yielded prematurely (before all the parallel "tasks" have been started) and async.map() stops any further processing (using yields basically turns it into a synchronous operation).
I am using a variable and that is used by many functions at a time. I need to synchronize it. How do I do it?
var x = 0;
var a = function(){
x=x+1;
}
var b = function(){
x=x+2;
}
var c = function(){
var t = x;
return t;
}
This is the simplified logic of my code. To give more insight, X is as good as my mongoDB object which needs to be used by only one function at a time. Also 3 functions are like REST api calls so there is probability they will be called at same time.
I need to write getX function which should manage locking and unlocking.
Any suggestions?
Node is single threaded so there is no chance of the the 3 functions to be executed at the same time. Syncronization and race conditions only apply in multithreaded environments. There is a case though, if the first function blocks for i/o.
You are asking about keeping a single object synchronized as several
asynchronous operations modify that object. This is a bit vague (do you need to execute them in order? do they change the same properties?) Its hard to make a catch all solution, so I suggest that you determine what order, if any, the operations must take place in, and use the async library to handle
the control flow.
The async.waterfall method (example below) is useful if you want to pass
results down a chain of functions that execute in order. There are many other
useful functions included in the library, like async.eachSeries (execute a function once per array item in order) and
async.parallel (execute an array of functions simultaneously.) All docs available at https://github.com/caolan/async
var async = require('async');
function calculateX(callback){
async.waterfall(
[
function(done){
var x = 0;
asyncCall1(x, function(x1){ // add x1=x+1;
done(null, x1);
});
},
function(x1, done){
asyncCall2(x1, function(x2){ // add x2=x1+2;
done(null, x2);
});
},
],
function(err, x2){
var t = x2;
callback(t);
});
};
calculateX(function(x2){
mongo.save(x2, function(err){ // or something idk mongo
if(err){ console.log(err) };
});
});
My function is like this for examle
function summ(a,b)
{
return a+b;
}
module.exports.summ = summ;
in other file:
var obj = require('./that file')
function app()
{
var s = obj.summ(7,7);
}
if i put console.log(s);
it is giving answer perfect.
My doubt is this will come all the time when request is coming frequently since i m using this kind of return in rest api ?
Or call back function is required like that result is
function summ(a,b,callback)
{
callback(a+b);
}
and
function app()
{
obj.summ(7,7,function(result){
var s = result;
}
}
As long as your summ function behaves in a synchronous manner, like it does in your example code, you don't have to use callbacks.
If you would use asynchronous functions in summ (anything I/O related, like reading a file, querying a database, opening a network connection), that would require passing a callback function because you would have to wait until the action is completed before you return the result (by calling the callback function).