2014-03-18 56 views
0

我發現自己在回調問題上停留了幾天,並且找不到任何方便的解決方案。這裏的問題是:在一個函數中包含的所有函數的末尾回調

我有一些jQuery的,看起來像

$(document).ready(function(){ 
    masterFunction_A(); 
    masterFunction_B(); 
}); 

function masterFunction_A() { 
    littleFunction_1(); 
    littleFunction_2(); 
    littleFunction_3(); 
    littleFunction_4(); 
    // etc... 
} 
function masterFunction_B() { 
    // do stuff 
} 

我想開始執行masterFunction_B()當所有littleFunctions()完成。當我嘗試將masterFunction_B()設置爲masterFunction_A()的回調函數時,似乎它在masterFunction_A()啓動了所有littleFunctions()時啓動,但當littleFunctions()結束時啓動它...

I嘗試:

  • 設置一個計時器,並在該定時器年底推出masterFunction_B(),但...這不是一個正確的方法在所有的littleFunctions它
  • 設置回調和計數的計數器直到調用正確的回調函數爲止,但我認爲有一種更好,更乾淨的方式來獲得我想要的。

你能幫忙嗎?

非常感謝!

- 編輯 -

這是masterFunction_A()的,居然叫loadContents()內容:

function loadContents() { 

    $.getJSON('data/data.json', function(data) { 

     for (var i = 0 ; i < data.length ; i++) { 
      $(".projects_ordered_list").append("<!-- PROJECT " + i + " -->"); 
      $(".projects_ordered_list").append("<li id='projects_ordered_list_item_" + i + "'></li>"); 
     } 

     for (var i = 0 ; i < data.length ; i++) { 

      $("#projects_ordered_list_item_" + i).load('projects.html', function() { 

       var this_html_id = $(this).attr("id"); 
       var this_id = this_html_id.substr(this_html_id.length - 1); 
       this__display_id = this_id; 
       this__display_id++; 

       $(this).find(".project_id").css("background", data[this_id].color); 
       $(this).find(".project_id_title").html(this__display_id + "."); 
       $(this).find(".project_name").html(data[this_id].name.en); 
       $(this).find(".project_date").html(" — " + data[this_id].date.en); 

       for (var j = 0 ; j < data[this_id].imgs.length ; j++) { 
        $(this).find(".bxslider").append("<li><img src='" + data[this_id].imgs[j] + "'></li>"); 
       } 


      }); 

     } 

    }); 

} 
+0

你的任何函數都是異步的嗎(他們做Ajax)?如果是這樣,你需要一個完全不同的策略。如果沒有任何異步,那麼你擁有它的方式應該工作得很好,因爲JavaScript是單線程的,並且不會同時運行兩個執行線程。如果'littleFunction_X()'是異步的,那麼當完成它們以便啓動'masterFunction_B()'時,你將不得不使用通知,並且我們需要更多地瞭解他們確切知道如何爲您提供建議。 – jfriend00

+0

是的,其實第一個叫做loadContents(),並且調用了$ .getJSON()。第二個被稱爲setDimensions(),併爲使用loadContents()加載的數據設置尺寸和樣式。 不好嗎? :D – faxime

+0

請向我們展示'littleFunction_1()'的實際代碼。你將不得不跟蹤它內部的ajax調用完成的時間。如果你返回從每個'littleFunction_X()'推遲的ajax,然後在所有這些函數上使用'$ .when()',你可以很容易地做你想要的,但是我們需要看到你的ajax代碼來專門提供建議。 – jfriend00

回答

0

使用內置於jQuery中的jQuery延遲a jax函數,你可以使它像這樣工作。

首先,讓您的每一個littleFunction_x()代碼看起來像這樣的:

function littleFunction_1() { 
    var d = $.getJSON(...) 
    // other code 
    return d; 
} 

然後,你可以這樣做:

$(document).ready(function(){ 
    $.when(masterFunction_A()).done(masterFunction_B); 
}); 

function masterFunction_A() { 
    var d = $.Deferred(); 
    $.when(littleFunction_1(), 
      littleFunction_2(), 
      littleFunction_3(), 
      littleFunction_4() 
    ).done(function() { 
     d.resolve(); 
    }); 
    return d; 
} 

想着它之後多一點,我覺得你也可以做一個稍微乾淨的版本,像這樣:

$(document).ready(function(){ 
    masterFunction_A().done(masterFunction_B); 
}); 

function masterFunction_A() { 
    return $.when(littleFunction_1(), 
      littleFunction_2(), 
      littleFunction_3(), 
      littleFunction_4() 
    ); 
} 
+0

謝謝!我現在就嘗試 – faxime

0

看看jQuery的遞延功能。我認爲這正是你需要的。

第一,創建一個推遲每個littleFunction:

dfd1 = $.Deferred(); 
dfd2 = $.Deferred(); 
dfd3 = $.Deferred(); 
dfd4 = $.Deferred(); 
在每個littleFunction

,解決在年底遞延:

function littleFunction1() { 
    ... 
    dfd1.resolve(); 
} 

... 

當所有Deferreds都解決了,開始執行master_Function_B:

$.when(dfd1, dfd2, dfd3, dfd4).then(masterFunction_B); 
+0

'littleFunction_X'中有ajax調用。他們已經有了自己的延期,不需要創建單獨的延期。 – jfriend00

+0

好的,我現在正在嘗試,我會讓你知道的。謝謝! – faxime

+0

是的,@ jfriend00提出的觀點是正確的。 – urz0r

相關問題