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

Wait for all .then() to be executed before firing a single function

本文关键字:then 执行 等待 单个 函数      更新时间:2023-09-26

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

我的问题是如何侦听所有的。then()完成,只有在那之后才触发我的foo()函数。

我试过使用when()和promise,但我没有成功地将其绑定到外部,而我已经设法将其绑定到loadTemplate(这不是我要找的)。

我总是可以将每个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
        });
      });
    }

loadTemplate函数返回一个promise,你可以使用。when()。请参阅文档示例,了解等待多个承诺解决的情况。

你可以这样做:

var promises = [];
$.each(templates.hbs, function (idx, template) {
    promises.push(loadTemplate(template.name));
});
$.when.apply($, promises).then(templateDone);
至于你的loadTemplate函数,你不需要创建你自己的promise。美元。Ajax默认返回一个承诺。
function loadTemplate(template) {
    return $.ajax({
        /* ... */
    });
}

看看这是否有影响?也可以尝试不使用async属性。我不知道为什么会这样,但值得一试。

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

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调用加载模板,也可以使用这种方法。$后调用函数。