问题
I have a workflow on JS, which should run several set by setTimeout functions one by one. How this could be done with JS/jQuery, preferably in some easy and beautiful way?
It looks like this
function recursiveOne(arg1){
if (allRight) return;
doSomething();
andAnotherOne();
setTimeout(function(){recursiveOne(arg1)}, 3000);
}
function coreFunction(){
recursiveOne(arg1);
recursiveTwo(arg2);
recursiveThree(arg3);
}
where recursiveTwo should start only when recursiveOne already done its last iteration.
The bad part is all functions work through setTimeout because I need to wait reaction from backend, and couldn't receive it directly - only by HTML source.
Possible solutions, that I could see:
- next function callback passed right in the previous function. Not too cool.
- jQuery deffered object, which isn't so beatiful too, but a bit better. The downside is I still should rise additional deffered request in each function I want to use this way.
回答1:
You have to use a callback or invoke coreFunction
directly. Below you can find a way to do it using array of functions.
function recursiveOne(arg1){
if(arg1 < 5){
arg1++;
setTimeout(function(){recursiveOne(arg1);}, 500);
}else{
console.log("func1 complete");
coreFunction();
}
}
function recursiveTwo(arg1){
if(arg1 < 10){
arg1++;
setTimeout(function(){recursiveTwo(arg1);}, 500);
}else{
console.log("func2 complete");
coreFunction();
}
}
function recursiveThree(arg1){
if(arg1 < 20){
arg1++;
setTimeout(function(){recursiveThree(arg1);}, 500);
}else{
console.log("func3 complete");
coreFunction();
}
}
var funcSet = [recursiveOne, recursiveTwo, recursiveThree];
var funcArgs = [[1], [5], [10]];
function coreFunction(){
if(funcSet.length){
var func = funcSet.shift();
func.apply(window, funcArgs.shift())
}
}
coreFunction();
回答2:
You will need to send the functions as callbacks
function recursiveOne(arg1, callback){
if (allRight) callback();
doSomething();
andAnotherOne();
setTimeout(function(){recursiveOne(arg1, callback)}, 3000);
}
function coreFunction(){
recursiveOne(arg1, function(){
recursiveTwo(arg2)
});
}
(Side note) I remember this project helped me alot when doing async stuff:
https://github.com/caolan/async
来源:https://stackoverflow.com/questions/12839488/how-to-queue-several-functions-set-by-settimeout-with-js-jquery