承诺和循环

时间:2016-11-03 19:14:26

标签: javascript ecmascript-6

我有这段代码:

function ProductObj(product, i) {
    var self = this;

    self.photo = product.photos.medium_half;
    self.title = product.name;
    self.tagline = product.tagline;
    self.url = product.url;

    self.htmlView = "";
    self.index = i;


    //this async call is slow, very slow
    self.updateHTML = function() {
        return new Promise(resolve => {
            $.get('product-template.html', function (template) {
                self.htmlView = template.replace('{image}', self.photo)
                    .replace('{title}', self.title)
                    .replace('{tagline}', self.tagline)
                    .replace('{url}', self.url);

                console.log('updateHTML ' + self.index + ' ran');
                resolve();
            });
        });
    };
}

当调用self.updateHTML时,同时调用self.updateDOM

 self.updateDOM = function() {
        return new Promise(resolve => {
            var thisHTML = '';

            for( var i = 0; i < self.products.length; i++) {

                if (i % 3 === 0 ) {
                    thisHTML += "<div class='row'>";
                    console.log('START')
                }

                thisHTML += self.products[i].htmlView;

                if ((i % 3 === 2) || i === (self.products.length - 1) ) {
                    thisHTML += "</div>";
                    console.log('finish')
                }

                if(i === (self.products.length -1)) {
                    $("#content").append(thisHTML);
                }
            }
            resolve();
        })
    }

很自然地,我用promises试图解决这个问题

 page.getProducts('data.json')
        .then( page.updateProductHTML )
        .then( page.updateDOM )
        .then( someOtherFunction );
首先执行

Page.getProducts并向page.updateProductHTML返回一个承诺。到目前为止,page.updateProductHTML中的承诺在self.updateHTML完成分配并且updateDOM被解雇之前就已解决,但在完成之前需要来自updateHTML的值

问题来自于此page.updateProductHTML,因为它运行此代码

self.updateProductHTML = function() {
        return new Promise(resolve => {
            for( var i = 0; i < self.products.length; i++){

                self.products[i].updateHTML();

            }
            resolve();
        })
    };

我尝试将上述代码包装在一个promise中,并在for循环之外解析,但$.get()调用仍然有效

根据我的理解,我需要将updateHTML保留在一个promise中,但它现在的状态似乎没有任何不同,因为我不能在{{1}中的for循环中使用.then }

如果在page.updateProductHTML完成调用之前,如何强制page.updateProductHTML无法解决?

小概述我想要这个订单self.updateHTML

2 个答案:

答案 0 :(得分:4)

您应该使用Promise.all()

self.updateProductHTML = function() {
  return Promise.all(self.products.map(product => product.updateHTML()));
};

答案 1 :(得分:1)

你可以使用promise.all,等待所有的promise都被解析,然后执行依赖于早期方法的其他方法。

我的Codepen链接

就是一个例子

&#13;
&#13;
self.updateProductHTML = function() {
  var updateMethods = [];
  for (var i = 0; i < self.products.length; i++) {
    updateMethods.push(self.products[i].updateHTML());
  }
  return Promise.all(updateMethods);
}

self.updateDOM = function() {
  for (var i = 0; i < self.products.length; i++) {

    if (i % 3 === 0) {
      thisHTML += "<div class='row'>";
      console.log('START')
    }

    thisHTML += self.products[i].htmlView;

    if ((i % 3 === 2) || i === (self.products.length - 1)) {
      thisHTML += "</div>";
      console.log('finish')
    }

    if (i === (self.products.length - 1)) {
      $("#content").append(thisHTML);
    }
  }
}

updateProductHTML().then(updateDOM);
&#13;
&#13;
&#13;