2012-08-29 17 views
6

在我的代碼中,我有一個函數調用數組。我循環這些調用並使用.apply()來調用它們。問題是,如果新函數的調用需要任何時間,循環將會應用()並在前一個函數完成之前調用下一個函數。 >。 <下面是一個例子:如何將回調添加到.apply()方法?

function someFunc(element, calls){ 
    if(calls.length){ 
    fn = calls[0]; 
    calls.shift(); 
    fn.apply(element, args); 
    someFunc(element, calls); 
    } 
} 

所以,如果有一個回調的應用功能,那麼這可能是工作我怎麼想它。即

function someFunc(element, calls){ 
    if(calls.length){ 
    fn = calls[0]; 
    calls.shift(); 
    fn.apply(element, args, function(){ 
     someFunc(element, calls); 
    }); 
    } 
} 

我也有一個關於在回調函數內調用someFunc的問題。我的calls陣列中的函數影響我的element變量。所以我想確保在它被修改後它會被傳遞給回調函數中的someFunc,所以下一個函數也可以處理它。有時候我會對this上下文感到困惑。 :)

如果有幫助,我使用jQuery。我知道如何給jQuery方法添加回調函數,但是我在處理原生JavaScript代碼時不知道該怎麼做。 如何添加回調到.apply()方法?

+1

除非您知道所有函數遵循的參數模式,否則沒有辦法做到您想要的。 – Pointy

+0

@Pointy - 爲什麼我需要一個參數模式,如果我把所有的參數都放到一個數組中又稱爲'args'? – Aust

+0

問題是無法判斷一個函數是否是異步的,並且設計爲接受一個回調函數參數(或兩個這樣的參數,或更多)。你不能讓系統「等待」一個函數,並且它的異步繼續完成。因此,如果你知道你的函數全部(例如)將回調作爲最後一個參數,那麼你可以解決一些問題。 – Pointy

回答

2

確保您調用的每個函數返回promise。然後,您可以「等待」這個承諾在您的列表中的下一個函數繼續之前「解決」:

function someFunc(element, calls) { 
    if (calls.length) { 
     var fn = calls.shift(); 
     fn.apply(element, args).done(function(el) { // what's args? 
      el = el || element; // default to previous element if necessary 
      someFunc(el, calls); 
     }); 
    } 
} 

與各功能看起來像:

function myFunc1(el) { 
    var def = $.Deferred(); 

    // do something async, and "resolve" the deferred object in the async callback 
    ...(function() { 
     def.resolve(el); // this "el" will get passed to the next function 
    }); 

    return def.promise(); 
} 

如果異步任務一個AJAX調用你可以直接返回$.ajaxjqXHR結果而不是創建一個新的延遲對象。

+0

如果我傳遞給我的'calls'變量的一些函數不是我的,我將如何添加'$。延遲()'對象?我可以用另一個函數來包裝它,還是甚至有可能? – Aust

+0

是的,你可以包裝函數,但是_somehow_你仍然必須「解析」承諾,並且必須在異步回調中完成。 – Alnitak

+0

因此,即使我將它包裹起來,我也會回到@Pointy提出的原始問題?也就是說,如果一個函數還沒有回調,那麼我想要的是不可能的? – Aust

相關問題