2016-04-08 33 views
0

我已經通過並嘗試了幾個同步調用函數的例子,但它似乎並沒有爲我工作。我使用外部句柄模板來生成一個加載了數據的'parent'html元素,然後在加載之後,我想從我創建的'child'模板(使用它們自己的數據)添加html。這兩個函數調用都調用相同的函數,但僅傳遞不同的模板/數據。以下是我對此的代碼 - 任何幫助表示讚賞。謝謝!不能讓這兩個函數同步調用

var loadSimpleCollection = function(templateFile, dataFile, containerSelector) { 

    var deferred = $.Deferred(); 

    $.get(templateFile, function(text) { 

    // Extract HTML from the template file 
    var raw_template = text; 

    // Compile that into an handlebars template 
    var template = Handlebars.compile(raw_template); 

    // Retrieve the container where the data will be displayed 
    var container = $(containerSelector); 

    // Fetch collection data from JSON file 
    $.getJSON(dataFile, function(data, status, xhr) { 
     $.each(data,function(index,element){ 
     var html = template(element); 
     container.append(html); 
     }); 
    }); 

    }); 

    return deferred.promise(); 

} 

loadSimpleCollection('template1.hbs', 'data1.json', '#parent-div').then(loadSimpleCollection('template1.hbs', 'data2.json', '#child-div')); 
+0

可能要包裝你'then'表達,否則它被立即調用。例如'.then(function(){loadSimpleCollection(...)})' –

+0

你需要在'container.append(html);' –

回答

0

有你的代碼中的多個問題:

  1. 你是不是永遠解決您的遞延
  2. 沒有必要創建自己的諾言 - 你可以回到你已經有了相當的承諾比使用the promise anti-pattern
  3. 你打電話.then()錯誤,如果你正在做其他承諾的東西,你的代碼甚至不會等待承諾。

我建議這樣的:

var loadSimpleCollection = function(templateFile, dataFile, containerSelector) { 

    return $.get(templateFile).then(function(text) { 

    // Compile that into an handlebars template 
    var template = Handlebars.compile(text); 

    // Retrieve the container where the data will be displayed 
    var container = $(containerSelector); 

    // Fetch collection data from JSON file 
    return $.getJSON(dataFile).then(function(data, status, xhr) { 
     $.each(data,function(index,element){ 
     var html = template(element); 
     container.append(html); 
     }); 
     return container; 
    }); 

    }); 

} 

loadSimpleCollection('template1.hbs', 'data1.json', '#parent-div').then(function() { 
    loadSimpleCollection('template1.hbs', 'data2.json', '#child-div') 
}); 

變化:

你已經有
  1. 回報的承諾,而不是創造新的deferreds。避免承諾反模式。
  2. 爲您的ajax調用使用promise。
  3. 鏈的兩個loadSimpleCollection()內部異步操作,以便它們將被連接在一起,當兩者都做
  4. 傳遞一個函數引用.then()因此它可以被稱爲後,不立即執行主叫方可以知道。

即使這一切,似乎奇怪加載和編譯相同template1.hbs兩次。您當然可以加載一次,編譯它,然後將其用於多個其他操作。

你也許可以使代碼的運行速度是這樣的:

var p1 = $.get('template1.hbs'); 
var p2 = $.getJSON('data1.json'); 
var p3 = $.getJSON('data2.json'); 
$.when(p1, p2, p3).then(function(t, d1, d2) { 
    var template = Handlebars.compile(t[0]); 
    var container = $('#parent-div'); 
    $.each(d1[0], function(index, element) { 
     container.append(template(element)); 
    }); 
    container = $('#child-div'); 
    $.each(d2[0], function(index, element) { 
     container.append(template(element)); 
    }); 
}); 
+0

完成後解析返回的承諾'deferred.resolve()'!像魅力一樣工作 - 感謝jfriend00! – Heath

+0

@Heath - 我添加了一個更快的選項,只加載模板一次,並行執行所有ajax調用。 – jfriend00

+0

@Heath - 由於您看起來可能是新手,您是否知道當您的問題得到解答時,您可以通過選擇最佳答案旁邊的綠色複選標記來向社區表明這一點?而且,在堆棧溢出的情況下,這也會爲您贏得一些聲望點。 – jfriend00