如何等待所有异步/同步循环完成?

时间:2019-10-03 01:05:43

标签: javascript asynchronous google-chrome-extension foreach

我创建了一个小的Chrome扩展程序,该扩展程序可以处理所有打开的标签页,并仅下载其中包含单个图像的标签页。该代码可以正常工作。

但是我还想等待代码中的所有循环和命令完成,因此在此之后,我可以开始跟踪是否已开始下载以及何时完成下载。 问题是我不知道如何等到整个循环过程及其内部同步/异步循环首先完成,然后再开始使用Chrome的api跟踪下载。

我知道有很多重复的主题,例如我的主题,它们提供了一些解决方案。我已经阅读过它们,并尝试使用异步/等待和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

我插入了两个警报,“完成”和“下载”。警报(“完成”)总是首先出现,然后警报(“下载”)第二出现。我希望在完成所有内部循环并启动所有下载(如果有)之后显示“完成”。

1 个答案:

答案 0 :(得分:0)

我将按照以下方式重写您的代码:-

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")
})