2014-05-08 85 views
0

我的问题是关于脚本文件运行的顺序(序列)。executeScript回调和异步函数

我打电话叫一个脚本文件“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' }); 
    } 
); 

从理论上讲,只有在“aaa.js”完成后,“bbb.js”文件才会执行。

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

是否所有任务(那些已放入队列,与相关异步行为的“aaa.js”)完全结束,在执行“bbb.js”之前?

回答

1

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

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


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

  1. 裹的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); 
    

    这将等到所有承诺执行requestNextInject前解决,或拨打handleError如果任何图像的加载失败。而通过“等待”,我的意思是“添加一个只能在承诺后执行的异步任务”。

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

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

如何做到这一点,在这种情况下? – user3059287

+0

@ user3059287编辑为包含一个可能的实现。异步的东西是棘手的;承诺只是解决这个问题的一种方式。 – Xan

+0

谢谢。我会尝试。 – user3059287