找到你要的答案

Q:Wait for all .then() to be executed before firing a single function [duplicate]

Q:等待所有。then()将触发一个函数之前执行[复制]

This question already has an answer here:

I'm trying to fire a function when all the templates are loaded. This is done via a loadTemplate function for each template.

My problem is how to listen for all the .then() to finish, and only after that to fire my foo() function.

I've tried using when() and promise, but I haven't been successful in binding that to the outside each, while I've manage to bind it to the loadTemplate (which isn't what I'm looking for).

I could always bind each loadTemplate to a counter, and on each iteration check if the counter has reached the number of templates on the each, but I'm sure there's a more elegant way to do this.

Here's the loop code:

    $.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;
          });
      });

and the function to fire after:

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

Thanks for the help!

Edit: Including the loadTemplate code as well:

    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功能。

我的问题是如何倾听所有。then()完成,只有经过那火我foo()功能。

我试着用when()和承诺,但是我没有绑定,到外面的都是成功,而我已经设法将其绑定到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
        });
      });
    }
answer1: 回答1:

As your loadTemplate function returns a promise, you can use .when(). See the documentation example for a case of waiting for multiple promises to be resolved.

You could do something like:

var promises = [];

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

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

As for your loadTemplate function, you don't need to create your own promise. $.ajax returns a promise by default.

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

See if that makes a difference? Also try without the async property. I'm not sure why that would fix it but it is worth trying.

当你LoadTemplate函数返回一个承诺,你可以使用。when()。有关等待多个要解决的问题的示例,请参见文档示例。

你可以做一些像:

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属性。我不知道为什么会修复它,但它值得尝试。

answer2: 回答2:

You can write simple condition to check if all the templates are loaded like this

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();
        }
      });
  });

I hope this works for you. You can use this approach even if you are loading templates with ajax calls. Calling function after $.each wont work if you are loading templates with ajax..

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

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加载模板,使用这种方法。美元后调用功能。每个不工作如果您正在加载模板与阿贾克斯..

javascript  jquery  ajax