I want to run func2 run only after func1 has finished.
{
func1();
func2();//
}
But when func1() starts, func2() does not wait for func1() to get finished. func2() run simultaneously with func1(), which causes run time error, because func2() need some input from func1().
I also tried using async module, but got no success.
Edit: I run the function check(), which call two functions prompt() and copyProject(). copyProject() should run only after prompt() function has finished, but it start executing simultaneously.
var check = function check (){
async.series([
function(callback){
prompt();
callback(null);
},
function(callback){
copyProject();
callback(null);
}
]);
};
var prompt = function prompt(){
var prompts = [{
name: "projectName",
message: "What is the name of your project?"
},{
name: "authorName",
message: "What is your name?",
}];
inquirer.prompt(prompts, function( answers ) {
for (var key in answers) {
if (answers.hasOwnProperty(key)) {
console.log(key + " -> " + answers[key]);
infoToRender[key] = answers[key]
}
}
});
};
var copyProject = function copyProject (){
// code to copy some files from one location to another based on input from prompt function
};
Your function prompt is itself an asynchronous function: The call to inquirer.prompts causes the function to wait and this makes it asynchronous. Since your prompt function does not use a callback, the async module can not know when prompt has finished: In contrast, it runs prompt and this function immediately returns. Hence async right afterwards runs copyProject.
What you need to do to solve this issue is to introduce a callback function in prompt that async "waits" for. So basically something like this:
var prompt = function (callback) {
// Do your stuff here...
inquirer.prompt(prompts, function (answers) {
// Your for loop here...
callback(null);
});
};
Then, within async you need to do:
async.series([
function (callback) {
prompt(callback);
},
function (callback) {
copyProject();
callback(null);
}
]);
Then copyProject is only run when prompt has been completed. Please note that async.series will not wait for copyProject to finish, in case this is an asynchronous function, as again, it does not take a callback. So same pattern applies here.
Related
Say I have a function as follows:
var randomFn = function(){
var response = '';
async.whilst(
// Test
function(){
return i < 5;
},
// Iteratee
function(callback){
// Random code that sets response to '5' after some attempts;
},
// Callback
function(err, n){
// Runs if error is encountered or iteratee stopped
}
);
return response;
}
The async module while allow the iteratee function to run repeatedly, until the first test function no longer returns true. My question is, can I be guaranteed the return for my randomFn() will only be executed once the everything inside the async function has completed?
So what exactly is the order of execution, or the rule for execution...?
I'm developing a Node.js app and I'm using Vorpal commands. I'm trying to send a value from the command to a function but i can't get it to work. Am I doing anything wrong?
Here is the code:
vorpal
.command('rollto <num>', 'Rolls to')
.action(function(num) {
rollto(num);
});
function rollto(num) {
bettime = bettimems % 60;
socket.emit('betting', bettime);
timer1 = setInterval(function () {
bettime--;
socket.emit('betting', bettime);
if (bettime == 0) {
socket.emit('random number', num);
console.log("Rolled to:" + num + "!!!");
clearInterval(timer1);
}
}, 1000);
}
The problem is that the function you pass to command's action has different arguments than you assume.
Here is the relevant part from docs:
.command.action(function)
This is the action execution function of a given command.
It passes in an arguments object and callback.
Actions are executed async and must either call the passed
callback upon completion or return a Promise.
And here is a working example:
var vorpal = require('vorpal')();
vorpal
.command('rollto <num>', 'Rolls to')
.action(function(arguments, callback) {
rollto(arguments, callback);
});
function rollto(arguments, callback) {
var num = arguments.num; // get 'num' parameter from arguments
timer1 = setInterval(function () {
console.log('test');
console.log(num);
clearInterval(timer1);
callback(); // Don't forget to use callback() to notify vorpal
}, 1000);
}
vorpal
.delimiter('myapp$')
.show();
Note that you actually have an async code inside setInterval, so you need to use callback() at the end to notify vorpal that processing is finished.
While attempting to use setTimeout to perform rate limiting on a monq worker, why is the worker not being throttled?
worker does not wait for 10 seconds before executing setTimeout(). Why is this and how can we get it to delay the call to foo()?
var monq = require('monq')
var client = monq('localhost/mydb')
var worker = client.worker(['general'])
worker.register({
test: function(params, callback) {
try {
setTimeout(foo(params, callback), 10000)
} catch(err) {
callback(err)
}
}
})
foo = function(params, callback) {
console.log('Hello world')
callback()
}
Because setTimeout expects a function reference. Instead, you're executing the function and passing the result to setTimeout.
Use:
setTimeout(function() {
foo(params, callback);
}, 10000);
Also, the try/catch block is somewhat redundant there, because the call to setTimeout won't throw an exception. Instead, you would need to handle it inside foo.
I think there is an easy solution for this, but for some reason I am not getting the expected results. My functions look like this:
var functionA = function(callback) {
loadData(fromURL1); // takes some time
loadData(fromURL2); // takes some time
callback(); // Should be called AFTER the loadData() functions are finished
}
var myCallBackFunction = function() {
// this function is called AFTER functionA() is finished
alert("All my loaded data from URL1 and URL2");
}
window.onload = function() {
functionA(myCallBackFunction);
}
Unfortunately, the callback() function above doesn't wait for loadData() to finish, and then just calls the alert with empty data.
I read a lot of online examples, but I think I am still missing something obvious.
If the loadData()s are async operations, you can do two things:
Using $.ajaxComplete():
var functionA = function(callback) {
loadData(fromURL1); // takes some time
loadData(fromURL2); // takes some time
$.ajaxComplete(function () {
callback(); // Should be called AFTER the loadData() functions are finished
});
}
Or chaining the functions:
var functionA = function(callback) {
loadData(fromURL1, function () {
loadData(fromURL2, function () {
callback(); // Should be called AFTER the loadData() functions are finished
}); // takes some time
}); // takes some time
}
Let's say I have a function in a file:
foo.js:
(function(){
return {
loadStuff: function(callback){
setTimeout(function() { callback() }, 2000)
}
}
})()
I have to run loadStuff in two different ways:
first: when I get the file loaded by javascript engine itself (let's say via XHR and eval), then I can call it passing a callback (that's already possible)
second: when it's loaded in a script tag, it still should call loadStuff automatically, although without a callback this time
How should I change the code to make loadStuff work both ways? I don't want to call loadStuff twice though: so for the first case I want to call it with callback, not like it would call it the first time function loaded (without callback) and then again with callback. I just need it to run loadStuff once, with callback.
So.
when <script src='foo.js' /> it should call loadStuff automatically
when the function is string and I do this:
fn = eval(fnStr)
fn.loadStuff(function(){
console.log("stuff loaded")
})
It should call loadStuff only once
Try
foo.js:
(function(){
var called = false,
loadStuff = function(callback){
called = true;
setTimeout(function() { callback && callback() }, 2000)
};
setTimeout(function(){!called && loadStuff();}, 13); //autolaunch if needed
return {
loadStuff: loadStuff
}
})()