executeScript回调和异步函数

时间:2014-05-08 15:06:04

标签: javascript google-chrome google-chrome-extension

我的问题是关于脚本文件运行的顺序(序列)。

我调用一个名为" aaa.js"的脚本文件。并且作为executeScript的回调,我有文件脚本" bbb.js",如下图所示是草图代码:

chrome.tabs.executeScript(tabid, {file:"aaa.js", runAt: 'document_start' },
  function() {
    chrome.tabs.executeScript(tabid, {file:"bbb.js", runAt: 'document_start' });
  }
);

理论上," bbb.js"文件仅在" aaa.js"之后执行。饰面。

自" aaa.js"使用image.onload = function(){...}的几个实例,并且onload事件处理程序的管理是异步的,我的问题是:

在执行&#34之前,是否所有任务(已放入队列,与#34; aaa.js&#34的异步行为相关;)完全结束 ; bbb.js"

1 个答案:

答案 0 :(得分:1)

不,不能保证。注入“aaa.js”的线程在异步任务完成之前终止,所以我希望在发生这种情况时立即注入“bbb.js”。

要实现您的目标,您需要确定所有异步任务终止的时刻,然后以sendMessage请求下一次注入,作为一种可能的机制。


根据请求,使用native JavaScript Promises提供这样做的一种可能方式

  1. 在Promise对象中包装onload:

    function onloadPromise(img, src, handler){
      return new Promise(function (resolve, reject){
        img.addEventListener('load', function(){
          resolve( handler(img) ); // Resolve promise with result of the function
        });
        img.addEventListener('error', function(){ 
          reject( Error("Image " + src + " could not be loaded") ); 
        });
    
        img.src = src;
      });
    }
    
  2. 定义处理程序:

    function onloadHandler(img){
      console.log("Done: " + img.src);
      /* Your handler code */
    }
    
    function handleError(err){
      console.error(err);
    }
    
    function requestNextInject(){
      console.log("All done");
      chrome.runtime.sendMessage({"onloadDone": true});
    }
    
  3. 假设数组imagessources,请创建一个承诺数组:

    var promises = [];
    for(var i in images){
      promises.push(onloadPromise(images[i], sources[i], onloadHandler));
    }
    

    根据需要更改此逻辑,重要的是为所有图像构建onloadPromise(img, src, handler)数组。

  4. 将它们连在一起:

    Promise.all(promises).then(requestNextInject).catch(handleError);
    

    这将等到所有Promise在执行requestNextInject之前解析,或者如果任何图像无法加载则调用handleError。而“等待”我的意思是“添加一个只会在承诺后执行的异步任务”。

  5. 在后台脚本中,注入第二个脚本:

    chrome.runtime.onMessage.addListener(
      function(request, sender, sendResponse){
        if(request.onloadDone) {
          chrome.tabs.executeScript(
            sender.tab.tabId,
            {file: "bbb.js"}
          );
        }
      }
    );