2016-04-29 43 views
0

我有點擊事件,調用FireCallBackEvents,並從那裏我傳遞的函數的數組都是回調。現在我想在function a()之後撥打function b(),這給出了我通過setTimeout()撥打電話的回撥結果。我期望它會延遲給出結果。如何使循環等待,直到回調回應價值

現在在下面的代碼中調用函數b和c之後調用第一個函數callback的alert。

這只是我真實代碼的一個示例。

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); 
     }); 
    } 
} 
+1

考慮使用jQuery「延遲對象」:http://www.vasanthk.com/jquery-promises-and-deferred-objects/ – paulsm4

+0

延遲不會幫助,因爲我試圖推廣回調函數,所以會有容易理解,因爲這是3個函數的例子我有20個函數在回調中會導致太多')};'在函數的末尾 – Kirtesh

+0

使用延遲將使我的程序更復雜 – Kirtesh

回答

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))); 
} 
+0

雅這將是有道理的,我應該嘗試這個' – Kirtesh

+0

你可以通過採取數組的單個副本,然後使用嵌套的IIFE執行僞遞歸,使第二個版本更高效。 – Alnitak

+0

感謝您的建議@Alnitak,我將它添加到這個答案。 – trincot

0

generalizeCallBack功能你不應該叫一個循環內的功能陣列。它不會幫助你延遲後面的函數(函數b和c)根據調用setTimeout的早期函數(函數a)的結果執行。

setTimeout函數只有在瀏覽器獲得下一個呼吸空間時纔會執行。這正好在你的函數循環之後。

解決的辦法是讓您的函數a返回一個承諾,並在承諾成功時執行其他函數(b和c)。

+0

如果你可以閱讀我寫的問題,這是一個示例代碼,setTimeout只是因爲延遲,因爲將有數據庫操作,我已經把setTimeout – Kirtesh

+0

如果你可以讀答案把你的數據庫操作放在承諾,並返回它。 ;) –