2016-11-03 3 views
0

У меня есть этот код:обещание и для петель

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

естественно, я использовал обещание, чтобы попытаться исправить это как такой

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

Я попытался обернуть вышеуказанный код обещанием и разрешить за пределами цикла for, но звонок $.get() все еще работает

от того, что я понимаю, мне нужно сохранить updateHTML в обещании, но оно, похоже, не делает то другое в своем нынешнем состоянии, так как я не могу использовать .then в мой цикл в page.updateProductHTML

Как заставить page.updateProductHTML не решить, пока он не закончит свои звонки в self.updateHTML?

небольшой резюмировать Я хочу, чтобы этот порядок self.getProducts() => self.updateProducts => sef.updateDOM => other functions

+0

могли бы вы разместить простое рабочее решение вашей проблемы? Это похоже на незначительную проблему с подключением. Было бы лучше понять проблему, если у вас есть образец. – Sreekanth

+0

Является ли 'product-template.html' одинаковым для каждого продукта? Затем вы можете получить его только один раз, прежде чем делать все в цикле, а updateHTML не должен быть асинхронным. – artem

+0

@artem вы правы, это ускоряет работу быстрее, чем мой метод updateDOM, но обещание все еще сломано. –

ответ

4

Вы должны использовать Promise.all():

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

Вы можете использовать promise.all, который ждет, пока все ваши обещания будут решены, а затем выполняет другие методы, зависят от более ранних методов.

Примером может служить здесь, на моей Codepen ссылке

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

Смежные вопросы