NodeJS: Recall function after finished - node.js

I have a function that does some work. When it is finished it calls the callback. After that I get the 'END' in console. But i need to execute again the same function. How can I do that? Thx.
function start(callback){
//... some work ...
if(work_finished){
callback();
}
}
start(function(){
console.log('END');
});

If your function is asynchronous, you can create a wrapper function and literally just call it again from the callback. Note, without any terminating conditions, this will run forever.
function start(callback){
//... some work ...
if(work_finished){
callback();
}
}
function run() {
start(function(){
console.log('END');
run();
});
}
If your function is not asynchronous, the above operation will eventually cause a stack overflow (due to infinite recursion) so you'd have to have the caller of start() trigger it again:
function start(callback){
//... some work ...
if(work_finished){
callback();
}
// then return true or false depending upon whether you want
// it to keep getting called again
return true;
}
function run() {
var more;
do {
more = start(function(){
console.log('END');
});
} while (more === true);
}
And, if you just want your function called on some regular time interval, you can use setInterval() like this:
// call my function every 5 seconds
var timer = setInterval(function() {
start(function(){
console.log('END');
});
}, 5000);

There are quite a few ways to repeatedly execute functions in node.
Recursive calls
code:
function start(callback){
//... some work ...
if(work_finished){
callback();
// call function again
// should be OK if some work is async so it doesn't
// block the thread
start(callback);
// or schedule to be called at end of event loop
// setImmediate(start, callback);
}
}
start(function(){
console.log('END');
});
Execute function any number of additional times which would require number of calls to be tracked
set the function up on an interval to be called ~n milliseconds
setInterval(start, 1000, callback);

Related

async.parallel`s function is working after another function has invoked callback function with error, why?

i was learning async library and just tried some codes myself and i am issueing a problem that can`t handle, can you please look at the code down below:)
async.parallel([
function (cb) {
setTimeout(() => {
let a = "asd";
console.log("AAA");
cb(a, null);
}, 2000);
},
function (cb) {
setTimeout( () => {
let b = "dasd";
console.log("BBBBB");
cb(b, null);
}, 5000);
}
], function (error, results) {
console.log("CCC");
console.log("Errors: " + error);
console.log("Results: " + results);
});
I supposed that BBB should NOT output to the screen, but to my surprise it DOES, can you help me understand why?
You are using async.parallel(). All asynchronous tasks will be executed without waiting for each other and the execution order is not guaranteed.
Here's a breakdown on how your script is executed:
Both setTimeout() are set.
2000 milliseconds later, console.log("AAA") and cb(a, null) are called.
cb(a, null) has an error. So the main callback is called, and async.parallel() ends.
But the story does not end here. The second setTimeout() is already set. Calling the main callback will not clear the timeout.
console.log("BBBBB") and cb(b, null) are called. This is why you see the output BBBBB.
Because the main callback is already called, calling cb(b, null) will not do anything.

Node.js - Unable to use callback in if statement

Hi I am trying to execute a callback in a if statement but I get "TypeError: callback is not a function"
This is my code:
socket.on('authenticate', function (data, callback) {
// this works
callback("false");
// this doesn't work
if (data == "abc") {
callback("true");
}
});
Always check if callable function is passed, at least just do if(callback)
in Your problem there may be situation that clientside not waiting for callback (done emit call without passing callback argument).
Try this solution:
socket.on('authenticate', function (data, callback) {
console.debug('socket authenticate:', data); // for debug purposes
if (data == "abc") {
if(callback) { // callback may not be passed
callback(null, true); // keep in mind in callbacks first argument is error second is result
}
return; // return will prevent execution to go down, because most of times used for resulting call.
}
if(callback) { // callback may not be passed
callback("Not authenticated", false);
}
});

nodejs: force callback execution if method hangs

i have a situation where my asynchronus nodejs method from a third party library is taking too long. i want to set a timeout limit on this call and if it does not return within that timeout, i want a callback to happen with default(empty) values.
current code
wrapperfunct(data, function(value, err) {
//do everything with value or err
})
wrapperfunc(data, callback) {
thirdpartylib.getData(input, callback)
}
i am noticing that getData sometimes hangs, that prevents the callback from happening. i want a behavior than if getData does not call the callback method in specified time, i call callback with default values, say (null, null).
You can make your own timeout like this:
wrapperfunc(obj, timeout, data, callback) {
var done = false;
var timer = setTimeout(function() {
done = true;
// callback with both values null to signify a timeout
callback(null, null);
}, timeout);
obj.thirdpartylib.getData(input, function(err, data) {
if (!done) {
clearTimeout(timer);
done = true;
callback(err, data);
}
})
}
Note: The value of this in your proposed function was probably not correct so I substituted obj. You will either have to pass that value in or you will have to use some variable that is within scope for that.

callback() or return callback()

It's possible I don't understand Node's event loop well enough.
Say I have a function foo which contains an asynchronous function async_func. Do I have
//1
function foo(callback) {
//stuff here
async_func(function() {
//do something
callback();
});
//this eventually get executed
}
or
//2
function foo(callback) {
//stuff here
async_func(function() {
//do something
return callback();
});
//never executed
}
Actually, in your sample 2, //never executed will be execute every time. It's returning from the callback, not from the wrapping function.
Sometimes the caller actually expects some return value and the behavior can change based on that. Another common reason to see a return callback() is just a clear way of short circuiting the function you're in. For example.
function doSomething(callback) {
something(function(err, data) {
if(err) return callback(err);
// Only run if no error
});
// Always run
}
Even though the return value isn't being used, it's using return to ensure that execution doesn't continue past the error conditional. You could just as easily write it this way which has the same effect.
function doSomething(callback) {
something(function(err, data) {
if(err) {
callback(err);
return;
}
// Only run if no error
});
// Always run
}

Should I be using process.nextTick

I'm trying to get my head around when to use process.nextTick. Below I'm using async library to control my code flow and was wondering if I should be calling nextTick in the end callback or not.
async.parallel([
function (callback) {
// do something
callback(data);
},
function (callback) {
// do something
callback(data);
}
],
// callback
function (data) {
process.nextTick(function () {
// do something
});
});
Without knowing exactly what your 'do something' is, I don't see any reason that you'd need to use nextTick in this situation. You use nextTick when you have reason to defer execution of a function to the next iteration of the event loop. You might want to read Understanding process.nextTick for more detail.
Also, note that async's parallel task completion callbacks take arguments err, data, so you should be doing:
async.parallel([
function (callback) {
// do something
callback(null, data);
},
function (callback) {
// do something
callback(null, data);
}
],
// callback
function (err, data) {
if (err) throw err;
// do something
});
The major difference being that the final callback is invoked immediately if one of the parallel tasks returns an error (calls callback with a truthy first argument).
My experience is that for async.parallel and other similar functions to work correctly, that you need to make all tasks definitely asynchronous; I love the async lib and it's my #1 choice over promises etc, but there can be some weird behavior if you don't force tasks to be async.
See here:
https://github.com/caolan/async#common-pitfalls-stackoverflow
so it should be:
async.parallel([
function(cb){
process.nextTick(function(){
doSomePotentiallySyncThing(cb);
});
},
function(cb){
process.nextTick(function(){
doSomePotentiallySyncThing(cb);
});
},
function(cb){
definitelyAsync(cb); // if it's **definitely** async, then we don't need process.nextTick
}
], function complete(err, results){
// we are in the final callback
});
I am 99% sure about this.

Resources