Timing issue in map / forEach while waiting for promise

So I have the a timing issue. What's going on is toDataUrl doesn't complete before chrome.storage.local.get is called. How can I refactor to have map or some other loop move on once the dataUrl is ready? I've tried async await, changing forEach to maps and vice versa. I've also tried while loops and counters but maybe I'm not implementing it correctly?

To clarify: what needs to happen is the chrome.storage.local.get needs to be called once all the loops have fully completed which doesn't currently happen.

To Data Url:

    const toDataURL = url => fetch(url)
      .then(response => response.blob())
      .then(blob => new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onloadend = () => resolve(reader.result)
        reader.onerror = reject
        reader.readAsDataURL(blob)
  }))

Main Body:

app.checkOfflineStorage = function(quotes) {

  let nQuotes = quotes;

  nQuotes.data.map(function(e, idx) {

    if(e.attachments) {
      e.attachments.data.forEach(function(el) {

        if(el.type === 'quote-picture') {

           toDataURL(`https://quotecatalog.imgix.net${el.value}?w=110`).then(function(res) { 

          el.dataURI = res;

        })
    }

  })
}

if(e.title) {
  if(typeof e.title.data.attachments !== 'undefined') {
    var title_attachments = e.title.data.attachments.data;

    title_attachments.forEach(function(el) {

 toDataURL(`https://quotecatalog.imgix.net${el.value}?w=110`).then(function(res) { 

        el.dataURI = res;
      })
    })
  }
}
  })


   chrome.storage.local.get('offlineCache', 


  if (Object.keys(storedQuoteArray).length === 0) {

    console.log(nQuotes)
    chrome.storage.local.set({"offlineCache": nQuotes}, function(res) {});

  } else {


    console.log(nQuotes)
    var combinedArray = storedQuoteArray.offlineCache.data.concat(nQuotes.data)

    combinedArray = combinedArray.slice(0, 100)
    console.log('100', combinedArray)

    chrome.storage.local.set({"offlineCache": {"data": combinedArray}}, function(res) {});
  }

   })
   }

1 answer

  • answered 2017-11-14 23:56 deiga

    A quick example of Promise.all:

    Promise.all(e.attachments.data.map(function(el) {
        if(el.type === 'quote-picture') {
           return toDataURL(`https://quotecatalog.imgix.net${el.value}?w=110`)
        }
    );)
    .then(function (resultArray) {
    // Handle results array
    });