I have this code:
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();
});
});
};
}
when self.updateHTML is called, self.updateDOM is called at the same time
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();
})
}
naturally, I used promises to attempt to fix this as such
page.getProducts('data.json')
.then( page.updateProductHTML )
.then( page.updateDOM )
.then( someOtherFunction );
Page.getProducts
executes first and returns a promise to page.updateProductHTML
. So far my promise in page.updateProductHTML
is resolving before assignments can finish in self.updateHTML
and updateDOM
is firing but it needs values from updateHTML before it can finish
The problem arises from this page.updateProductHTML
as it runs this code
self.updateProductHTML = function() {
return new Promise(resolve => {
for( var i = 0; i < self.products.length; i++){
self.products[i].updateHTML();
}
resolve();
})
};
I attempted to wrap the above code in a promise and resolve outside of the for loop but the $.get()
call is still working
from what I understand I need to keep updateHTML in a promise but it doesn't seem to do anything different in its present state since I can't use a .then
in my for loop in page.updateProductHTML
How do I force page.updateProductHTML
to not resolve until it finishes its calls in self.updateHTML
?
small recap I want this order self.getProducts() => self.updateProducts => sef.updateDOM => other functions
You should use Promise.all()
:
self.updateProductHTML = function() {
return Promise.all(self.products.map(product => product.updateHTML()));
};
You could use promise.all, which waits till all of your promises are resolved and then executes the other methods which are dependent on the earlier methods.
An example is here on my Codepen link
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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.