在触发单个函数之前等待所有.then()执行

时间:2015-10-08 10:27:00

标签: javascript jquery ajax

我尝试在加载所有模板时触发一个函数。这是通过每个模板的loadTemplate函数完成的。

我的问题是如何监听所有.then()完成,并且只有在那之后才能激活我的foo()函数。

我尝试过使用when()和promise,但是我没有成功地将它绑定到外部,而我已经设法将它绑定到loadTemplate(这不是&# 39,我正在寻找的东西。

我总是可以将每个loadTemplate绑定到一个计数器,并且在每次迭代时检查计数器是否已达到每个模板上的模板数量,但我确信这是一种更优雅的方法。

这是循环代码:

    $.each(templates.hbs, function(idx, template) {
        loadTemplate(template.name)
          .then(function(templateStr){
            var compiledTemplate = Handlebars.compile(templateStr);
            if(template.isPartial){
              Handlebars.registerPartial(template.key, compiledTemplate);
            }
            templates[template.key] = compiledTemplate;
          });
      });

以及之后开火的功能:

    function templateDone(){
      console.log("done!");
    }

感谢您的帮助!

编辑:包括loadTemplate代码:

    function loadTemplate (template) {
      return new Promise(function (resolve, reject) {
        $.ajax({
          url: config.wwwroot + '/folder/' + template + '.hbs',
          async: false,
          success: function (result) {
            resolve(result);
          },
          error: reject
        });
      });
    }

2 个答案:

答案 0 :(得分:2)

当你的loadTemplate函数返回一个promise时,你可以使用.when()。有关等待多个承诺得到解决的情况,请参阅documentation示例。

您可以执行以下操作:

var promises = [];

$.each(templates.hbs, function (idx, template) {
    promises.push(loadTemplate(template.name));
});

$.when.apply($, promises).then(templateDone);

至于你的loadTemplate功能,你不需要创建自己的承诺。 $ .ajax默认返回一个承诺。

function loadTemplate(template) {
    return $.ajax({
        /* ... */
    });
}

看看是否有所作为?也可以尝试不使用async属性。我不确定为什么会解决它,但值得尝试。

答案 1 :(得分:1)

您可以编写简单的条件来检查是否所有模板都像这样加载

var loaded_template = 0;  
$.each(templates.hbs, function(idx, template) {
    loadTemplate(template.name)
      .then(function(templateStr){
        var compiledTemplate = Handlebars.compile(templateStr);
        if(template.isPartial){
          Handlebars.registerPartial(template.key, compiledTemplate);
        }
        templates[template.key] = compiledTemplate;
        loaded_template++;
        if(loaded_template == templates.hbs.length){
         foo();
        }
      });
  });

我希望这适合你。即使您使用ajax调用加载模板,也可以使用此方法。如果你用ajax加载模板,$ .each之后的调用函数将不起作用..