如何使for循环等待,直到回调响应值

时间:2016-04-29 07:08:19

标签: javascript jquery callback settimeout

我有点击事件,它调用FireCallBackEvents并从那里传递所有回调的函数数组。现在我想在function b()之后拨打function a(),这会给出我通过setTimeout()调用的回调结果。我希望它能延迟给出结果。

现在在下面的代码中,在调用函数b和c之后调用第一个函数回调。

这只是我真实代码的一个示例。

function FireCallBackEvents(){
    generalizeCallBack([a,b,c]);
}

function a(parameter1, parameter2,callback){
    alert("Hello World: " + parameter1 + " : " + parameter2);
    setTimeout(function(){callback("12")},600);
}
function b(parameter1, parameter2,callback){
    alert("Hello World1: " + parameter1 + " : " + parameter2);
    callback("123");
}
function c(parameter1, parameter2, callback){
    alert("Hello World2: " + parameter1 + " : " + parameter2);
    callback("1234");
}

function generalizeCallBack(arrayOfFunctions){
    for(var i = 0; i < arrayOfFunctions.length; i++){
        arrayOfFunctions[i]("1","2",function(we){
            alert(we);
        });
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用上一个函数的这个变体,它从您传递的回调函数中递归调用它:

function generalizeCallBack(arrayOfFunctions){
    if (!arrayOfFunctions.length) return; // nothing to do
    var func = arrayOfFunctions.shift(); // extract function to execute
    func("1","2", function(we){
        alert(we);
        generalizeCallBack(arrayOfFunctions); // recurse with shorter array
    });
}

请注意,这会更改您传递的数组。如果您希望呼叫者保持阵列,请使用slice而不是shift

function generalizeCallBack(arrayOfFunctions){
    if (!arrayOfFunctions.length) return; // nothing to do
    var func = arrayOfFunctions[0]; // get function to execute
    func("1","2", function(we){
        alert(we);
        generalizeCallBack(arrayOfFunctions.slice(1)); // recurse with shorter array
    });
}

由于此版本在每次(递归)调用时都会获取一个数组副本,因此我们可以通过第一次执行此操作来提高效率(如@Alnitak所建议的那样):

function generalizeCallBack(arrayOfFunctions){
    function recurse (arrayOfFunctions) {
        if (!arrayOfFunctions.length) return; // nothing to do
        var func = arrayOfFunctions.shift(); // extract first function
        func("1","2", function(we){
            alert(we);
            recurse(arrayOfFunctions); // recurse with shorter array
        });
    }
    // take copy (slice) of array in order not to alter the caller's array:
    recurse(arrayOfFunctions.slice(0));
}

这样只能获取一个数组副本。递归部分在同一个副本上工作,随着它在递归链中向下变短。

这是相同的,但是写成一个立即调用的函数表达式:

function generalizeCallBack(arrayOfFunctions){
    (function recurse (arrayOfFunctions) {
        if (!arrayOfFunctions.length) return; // nothing to do
        var func = arrayOfFunctions.shift(); // extract first function
        func("1","2", function(we){
            alert(we);
            recurse(arrayOfFunctions); // recurse with shorter array
        });
        // take copy (slice) of array in order not to alter the caller's array:
    }(arrayOfFunctions.slice(0)));
}

答案 1 :(得分:0)

您不应在generalizeCallBack函数的循环内调用函数数组。根据调用setTimeout的早期函数(函数a)的结果,延迟执行后面的函数(函数b和c)无助于它。

setTimeout功能仅在浏览器获得下一个呼吸空间时执行。这是在你的函数循环之后。

解决方案是让你的函数a返回一个promise并在promise成功时执行其他函数(b和c)。