0

我正在寻找一种能够运行不同功能的解决方案,但其中一些需要超时,并且所有后续功能都需要等到前一个功能完成。每个功能都应该能够打破完整的过程。

现在我想将所有函数推入堆栈并循环遍历它们:

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。

4

2 回答 2

2

注意:我已经更新了我的答案,请参阅帖子底部。

好吧,让我们来看看。

您正在使用该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);
于 2012-03-01T15:54:13.973 回答
1

这正是承诺解决的方案。特别是,可以破坏承诺这一事实非常适合您的情况,因为破坏的承诺会阻止链继续(就像同步代码中抛出的异常一样)。

例如,使用上面链接的幻灯片中讨论的Q Promise 库:

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();
于 2012-03-01T16:56:31.473 回答