Как дождаться завершения всех циклов асинхронизации / синхронизации? - PullRequest
0 голосов
/ 03 октября 2019

Я создал небольшое расширение Chrome, которое обрабатывает все открытые вкладки и загружает только вкладки с отдельными изображениями в нем. Код работает нормально.

Но я также хочу дождаться завершения всех циклов и команд в моем коде, поэтому после этого я могу начать отслеживать, начались ли какие-либо загрузки и когда они завершены. Проблема в том, что я не знаю, как дождаться полного завершения всего цикла цикла с его внутренними циклами sync / async, прежде чем я начну отслеживать загрузку с помощью API Chrome.

Я понимаю, что есть много повторяющихся тем, таких какмои собственные, которые предоставляют некоторые решения. Я прочитал их и попытался использовать некоторые методы, такие как async / wait и All.promises, и заменить tabs.forEach на tabs.map. Но я не могу заставить его работать, единственный прогресс, который я сделал, это дождаться окончания всего цикла forEach, но проблема остается с асинхронной функцией chrome.tabs.executeScript, которая все еще выполняется.

это мой оригиналкод без попытки решения. все работает как есть.

chrome.tabs.query({currentWindow: true}, function(tabs) {//1
       tabs.forEach(tab => {//2
        console.log('Tab ID: ', tab.id);
        console.log('Tab URL: ', tab.url);
        console.log('Tab TITLE: ', tab.title);      
        chrome.tabs.executeScript(tab.id, {code: 'document.contentType'}, ([ mimeType ]) => {//3
        var mediav1=mimeType;                   
        for (var i = 0, iLen = mediaArray.length; i < iLen; i++) {//4
            if (mediav1.indexOf(mediaArray[i]) > -1) {                         
               chrome.downloads.download({
               url: tab.url, 
               conflictAction: 'uniquify', 
               saveAs: false
               },
               function(){      
               alert("Download")
               });
              }           
        }//4             
        });//3
    });//2
alert("Done")
 });//1

Я вставил два оповещения: Готово и Загрузка. Предупреждение («Готово») всегда появляется первым, а затем - предупреждение («Загрузка»). Я хочу, чтобы сообщение Done отображалось после завершения всех внутренних циклов и начала всех загрузок (если они есть).

1 Ответ

0 голосов
/ 14 октября 2019

Я бы переписал ваши коды следующим образом: -

const execScript = (tab) => {
  return new Promise((resolve, reject) => {
    chrome.tabs.executeScript(tab.id, {code: 'document.contentType'}, ([ mimeType ]) => {//3
      var mediav1=mimeType;
      for (var i = 0, iLen = mediaArray.length; i < iLen; i++) {//4
        if (mediav1.indexOf(mediaArray[i]) > -1) {
          chrome.downloads.download({
              url: tab.url,
              conflictAction: 'uniquify',
              saveAs: false
            },
            () => {
              resolve("Done")
            });
        }
      }//4
    });//3  
  });
}

//then get all tabs and then create a function call
chrome.tabs.query({currentWindow: true}, async (tabs) => {
  const promiseArray = tabs.map(tab => {
    return execScript(tab);
  })
  const result = await Promise.all(promiseArray);
  console.log(result);
  console.log("Done")
})
...