How to pass value between Async.series functions without global variable - node.js

var Async = require('async');
var Test_Hander = function () {
};
Test_Hander.prototype.begin = function () {
Async.series([
this.first, // this.first.bind(this) does not work either
this.second
],function (error) {
if (error) {
// shit
}
else {
// good
}
});
};
Test_Hander.prototype.first = function (callback) {
console.log('Enter first function');
callback(null,'I am from first function');
};
Test_Hander.prototype.second = function (one, callback) {
console.log('Enter second function');
console.log('parameter one: ');
console.log(one);
console.log(callback);
callback(null);
};
var hander = new Test_Hander();
hander.begin();
I want to pass some value from function first to function second. And I know that waterfall and global variable are both ok. However, can I just pass a result value from function first to function second without using waterfall and global variable?

Using promise you can chain the methods and execute the code similar to async.series and you don't need to require a async module.
var Test_Hander = function () {
};
Test_Hander.prototype.begin = function () {
this.first()
.then(this.second)
.catch(function(err){
// Handle error
});
};
Test_Hander.prototype.first = function (callback) {
return new Promise(function(reject, resolve){
// do something
// if err : reject(err)
// else : resolve(data);
});
};
Test_Hander.prototype.second = function (responsefromFirst) {
// Do somethign with response
};
var hander = new Test_Hander();
hander.begin();

Related

about complicated biz logic in async

I am new in node.js and have some confusied questions about async. See the code below.
var async = require('async');
const func = function func(cb) {
cb(null, 'hello');
}
const func1 = function func1(param1, cb) {
console.log(param1);
cb(null, 'hello', 'world');
}
const func2 = function func2(param1, param2, cb) {
console.log(param1, ' ', param2);
cb(null, 'result');
}
async.waterfall([func, func1, func2], (err, result)=> {
console.log(result);
});
Yes, we know the function will run one by one. My question is, if I have some complicated condition logic based on different result from the function. Is that mean I have to use await and re-write the return code for the functions?
async function doIt() {
const t= await func(parms);
... biz logic ...
const t1= await func1(t);
... biz logic ...
const t2= await func2(t1);
... biz logic ...
}
doIt();
One option (disclaimer: not very elegant...) would be to define variables at the global scope (so they are accessible everywhere), and then use async.series to perform any sequential tasks or complex logic you need to perform:
var async = require('async');
var param1;
...
var result;
async.series([
function(cb) {
func(function() {
param1 = ...;
cb(null);
}
},
function(cb)
// biz logic
},
function(cb) {
func1(param1, function() {
cb();
}
},
// etc.
], function(err) {
if (err) {
console.error(err);
} else {
console.log(result);
}
});
Otherwise, you can use promises, which will be more readable.

Async series is not calling properly

I have 3 function has to call in series one after the other. but first function is exeucting and in between second and third are executing.
var tasklist=[api_hit,delay,mysql_check];
if(task_list.length>0){
async.series(
tasklist,
function(err, response) {
console.log(err);
console.log(response);
results.data=response;
results.message="Completed";
console.log(results);
}
);
}
Internal functions:
function api_hit(callback){
console.log("Inside api");
var ele=task_list[0];
var apidata=[];
var msg={'data':[]};
apiinfo.forEach((item,key)=>{
if(item.Method_name==ele.Parameters){
//Here checking random Int value
if(item.Value=="{{$randomInt}}"){
item.Value = generate(25);
}
apidata.push(item);
}
});
var data=[];
data['api']=apidata;
apiModel.validateAPI(data,function(res){
console.log("result api");
msg.data=res;
msg.case='api_hit';
callback(msg);
});
}
function delay(callback){
console.log("Inside delay");
var msg={'data':[]};
global_vars.sleep(1000);
msg.data='success';
msg.case='task';
console.log("after delay");
callback(msg);
}
function mysql_check(callback){
console.log("inside mysql");
var ele=task_list[2];
var dbdata=[];
var msg={'data':[]};
dbchecks.forEach((item,key)=>{
if(item.query_id==ele.Parameters){
console.log(item.query+" ::: "+ele.Parameters);
dbdata.push(item);
}
});
data['dbdata']=dbdata;
apiModel.checkmysql(data,function(err,res){
if(err) throw err;
console.log("inside mysql res");
msg.data=res;
msg.case='task2';
callback(msg);
});
}
My intention is to call these function after completing of others and all the results has to process in a single variable. but in api_hit method when it is executing another function inside of it then delay()(second function of async) is executing. how to stop this and make it in sequence. thanks in advance.
The first argument to the callback function is the error, pass null in case of success.
'use strict'
const async = require('async')
function api_hit(callback) {
setTimeout(() => {
console.log('Completed api_hit')
callback(null, 'api_hit')
}, 1000)
}
function delay(callback) {
setTimeout(() => {
console.log('Completed delay')
callback(null, 'delay')
}, 100)
}
function mysql_check(callback) {
setTimeout(() => {
console.log('Completed mysql_check')
callback(null, 'mysql_check')
}, 500)
}
var tasklist = [api_hit, delay, mysql_check];
if (tasklist.length > 0) {
async.series(
tasklist,
function (err, response) {
console.log(err);
console.log(response);
}
);
}
Doc link: https://caolan.github.io/async/docs.html#series

Function enters then before request completed

My async function enters then before request is completed. Shouldn't Then part of the code executes only after the async function is completed? How to make the function call only when all the function has finished executing?
app.js
var request_test = require('./request_test');
baseUrl = "https://github.com";
promiseFunction().then((result)=>{
console.log("complete")
});
var promiseFunction = async function promiseFunction() {
request_test.request_test(baseUrl);
}
request_test.js
var request = require('request');
var cheerio = require('cheerio');
var request_test = function check(baseUrl) {
console.log("baseUrl:" + baseUrl)
var options = {
url: baseUrl
};
request(options, function (error, response, html) {
if (!error) {
console.log("no error");
}else{
console.log("else js");
console.log(error);
}
});
}
module.exports = {
request_test: request_test
};
In order to use then() you need to return a promise. So here is an example of the good old style promise chain, simply return promise from request_test and once you resolve or reject it, then() will be called:
promiseFunction().then((result) => {
console.log("complete");
});
function promiseFunction() {
return request_test();
}
function request_test() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("no error");
resolve();
}, 1000);
});
}
Or maybe use the modern approach - async method to await call function that returns promise.
promiseFunction();
async function promiseFunction() {
await request_test();
console.log('complete');
}
function request_test() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log("no error");
resolve();
}, 1000);
});
}
Your issue is coming from var request_test = function check(baseUrl) { ... inside this function you are not returning promise, you are even returning nothing :)
if you are using async I would go ahead and use the await/async syntax. Also the package request does not return a promise, you have an alternative with request-promise-native. The promise should be the return value of your helper function. It could look like this:
var request_test = require('./request_test');
var baseUrl = "https://github.com";
var promiseFunction = async function () {
var result = await request_test.request_test(baseUrl);
console.log("complete");
}
promiseFunction();
and the module:
var request = require('request-promise-native');
var cheerio = require('cheerio');
var request_test = function check(baseUrl) {
console.log("baseUrl:" + baseUrl)
var options = {
url: baseUrl
};
return request(options).then(function (error, response, html) {
if (!error) {
console.log("no error");
} else{
console.log("else js");
console.log(error);
}
});
}
module.exports = {
request_test: request_test
};

Async parallel and promises wont work

I have the following two snippets:
1.this is the unit I would like to run:
health.checkHealth = function (req, res) {
async.parallel({
cassandra: function (callback) {
cassandraRepository.ping(callback);
},
kafka: function (callback) {
kafkaHelper.ping(callback);
},
vault: function (callback) {
vaultClient.health()
.then((isOk)=>{
callback(null, isOk)})
.catch(()=>
callback(null, false));
}
}, function (err, result) {
var response = {};
if (result.cassandra) {
response.cassandra = "OK";
} else {
response.cassandra = "Failed";
res.status(500);
}
if (result.kafka) {
response.kafka = "OK";
} else {
response.kafka = "Failed";
res.status(500);
}
if (result.vault) {
response.vault = "OK";
} else {
response.vault = "Failed";
res.status(500);
}
res.send(response);
})
}
2.this is the test to check the unit:
describe('vault is avaliable', function () {
beforeEach(sinon.test(function () {
sinon.stub(vaultClient, "health").resolves(true);
}));
it('should return 200', sinon.test(function (done) {
var response = {
vault: "OK"
};
var req = {};
var res = {};
var spySend = res.send = sinon.spy();
var spyStatus = res.status = sinon.spy();
health.checkHealth(req, res);
expect(spySend.calledOnce).to.equal(true);
expect(spySend.calledWith(response));
expect(spyStatus.calledOnce).to.equal(false);
}));
});
My problem is that when I call checkHealth it proceeds to the next line (expect(spySend.calledOnce).to.equal(true);) without waiting for the vaultClient's promise to complete.
What do I need to do to make the expects run only after the 'checkHealth' was run.
You do not need to use the async - you can use promises directly in your code with Promise.all as others have suggested.
The code here is using promisifyAll from Bluebird, but you can also convert the APIs to use promises yourself.
//.props is bluebird, you can `.all` with native promises too
Promise.props({
cassandra: cassandraRepository.pingAsync(); // created by promisifyAll
kafka: kafkaHelper.pingAsync(),
vault: vaultClient.health()
}).then(results => {
// access results.cassandra, results.kafka and results.vaule here
});

Object [object Object] has no method 'test'

I am trying to use a function in another module i am not able to use it may i know what is the issue?
this.test = function(callback) {
callback('i am test');
};
module.exports.config = function (settings, callback) {
this.test(function(err,res){
console.log(res);
});
};
The value of this is different because you're inside another function. Try this instead:
this.test = function(callback) {
callback('i am test');
};
var self = this;
module.exports.config = function (settings, callback) {
self.test(function(err,res){
console.log(res);
});
};
Or just give the function name and call it directly:
function test(callback) {
callback('i am test');
};
module.exports.config = function (settings, callback) {
test(function(err,res){
console.log(res);
});
};

Resources