我正在寻找一个可以运行不同函数的解决方案,但其中一些函数需要超时,所有后续函数都需要等待上一个函数完成。每个函数都应该能够打破整个过程。
现在我想把所有函数都推到一个堆栈中,并在其中循环:
function foo() {
// bar() should wait as long the following is finished:
setTimeout(function(){
if ((new Date()).getSeconds() % 2) {
alert('foo');
// break loop through functions (bar is not called)
}
else {
// start next function (bar is called)
}
}, 1000);
}
function bar() {
setTimeout(function(){
alert('bar')
}, 1000);
}
var functions = new Array('foo', 'bar');
for (var i = 0, length = functions.length; i < length; i++) {
window[functions[i]]();
}
但是如何包含等待/休息?!
注意:这应该适用于2个以上的功能(功能数量可变)
注意2:我不想使用jQuery。
注意:我已经更新了我的答案,请参阅文章底部
好的,让我们看看。
您使用的是window[func]()
方法,因此应该能够存储和使用每个函数的返回值。
证明:
function a(){
return "value";
}
var ret_val = window['a']();
alert(ret_val);
让我们创建一个返回规则:
如果函数返回true
,则继续执行流程
如果函数返回false
,则中断执行流程。
function a(){
//Do stuff
return (condition);
}
for(i = 0; i < n; i++){
var bReturn = window['function']();
if(!bReturn) break;
}
现在让我们把它付诸实践。
function a(){
//Do stuff
return ((new Date()).getSeconds() % 2); //Continue?
}
function b(){
//Do stuff
return true; //Continue?
}
function c(){
//Do stuff
return false; //Continue?
}
function d(){
//Do stuff
return true; //Continue?
}
var functions = new Array('a', 'b', 'c', 'd');
for (var i = 0; i < functions.length; i++ ) {
var bReturn = window[functions[i]]();
if(!bReturn) break;
}
根据您执行脚本的时间,例如,在一个均匀或不均匀的时间段内,它将只执行函数a
或函数a
b
&c
。在每项活动之间,您可以进行正常的业务
当然,在您的情况下,条件可能因每个单独的功能而异。
这里有一个JSFiddle示例,您可以在其中看到它的实际操作。
例如,通过一些小的修改,您可以使其成为这样,如果函数a
返回false,它将跳过下面的函数,继续执行下一个或之后的函数。
更改
for (var i = 0; i < functions.length; i++ ) {
var bReturn = window[functions[i]]();
if(!bReturn) break;
}
到此
for (var i = 0; i < functions.length; i++ ) {
var bReturn = window[functions[i]]();
if(!bReturn) i++;
}
将使它跳过一个函数,每次函数返回false。
你可以在这里试试。
顺便说一句,如果你正在寻找一个"暂停"脚本的等待函数,你可以使用这段代码。
function pausecomp(millis){
var date = new Date();
var curDate = null;
do {
curDate = new Date();
}while(curDate-date < millis);
}
更新
调整代码后,它现在可以与setTimeout
一起使用。
这个想法是,您有一个入口点,从数组中的第一个函数开始,传递一个当前在数组中的索引参数,然后用一个递增索引来执行下一个函数。
示例|代码
function next_function(index){
if(index >= functions.length) return false;
setTimeout(function(){
window[functions[index+1]](index+1);
}, 1000);
}
function a(index){
//Do stuff
if(((new Date()).getSeconds() % 2)) return false; //Stop?
next_function(index);
}
function b(index){
//Do stuff
if(false) return false; //Stop?
next_function(index);
}
function c(index){
//Do stuff
if(true) return false; //Stop?
next_function(index);
}
function d(index){
//Do stuff
if(false) return false; //Stop?
next_function(index);
}
var functions = new Array('a', 'b', 'c', 'd');
//entry point
window[functions[0]](0);
这正是promise解决的场景。特别是,承诺可能被破坏这一事实非常适合您的情况,因为被破坏的承诺会阻止链继续(就像同步代码中抛出的异常一样)。
例如,使用上面链接的幻灯片中讨论的Q承诺库:
function fooAsync() {
return Q.delay(1000).then(function () {
if ((new Date()).getSeconds() % 2) {
alert("foo");
throw new Error("Can't go further!");
}
});
}
function barAsync() {
return Q.delay(1000).then(function () {
alert("bar");
});
}
var functions = [fooAsync, barAsync];
// This code can be more elegant using Array.prototype.reduce, but whatever.
var promiseForAll = Q.resolve();
for (var i = 0; i < functions.length; ++i) {
promiseForAll = promiseForAll.then(functions[i]);
}
// Of course in this case it simplifies to just
// promiseForAll = fooAsync().then(barAsync);
promiseForAll.then(
function () {
alert("done!");
},
function (error) {
alert("someone quit early!");
// and if you care to figure out what they said, inspect error.
}
).end();