无法同步调用这两个函数

时间:2016-04-08 16:47:21

标签: jquery function handlebars.js synchronous deferred

我已经查看并尝试了几个同步调用函数的示例,但它似乎并不适合我。我正在使用外部车把模板来生成一个加载了数据的“父”html元素,然后在加载之后,我想要从我创建的“子”模板(使用他们自己的数据)中添加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'));

1 个答案:

答案 0 :(得分:0)

您的代码存在多个问题:

  1. 您永远不会解决您的延期
  2. 没有必要创建自己的承诺 - 您可以返回已有的承诺而不是使用the promise anti-pattern
  3. 你正在调用.then()错误,这样如果你正确地做其他承诺,你的代码甚至不会等待承诺。
  4. 我建议:

    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. 返回您已有的承诺,而不是创建新的延期。避免承诺反模式。
    2. 使用promises进行ajax调用。
    3. loadSimpleCollection()内链接您的两个异步操作,以便将它们链接在一起,并且调用者可以知道两者何时完成
    4. 将函数引用传递给.then(),以便稍后调用,而不是立即执行。
    5. 即使有了这一切,加载和编译相同的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));
          });
      });