2014-05-08 2 views
0

Мой вопрос касается порядка (последовательности), который запускаются в файлах сценариев.callback callback и асинхронные функции

Я называю файл сценария с именем «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 является асинхронным, мой вопрос:

ли все задачи (которые попали в очереди, связанные с к асинхронное поведение «aaa.js») полностью завершено, перед исполнением «bbb.js»?

ответ

1

Нет, гарантии нет. Поток, который вводит «aaa.js», запускается до завершения асинхронных задач, поэтому я ожидаю, что «bbb.js» будет введена, как только это произойдет.

Для достижения того, что вы хотите, вам нужно определить момент завершения всех ваших задач асинхронной работы, а затем запросить следующую инъекцию с помощью sendMessage в качестве возможного механизма.


По желанию, обеспечивая один возможный путь сделать это, используя native JavaScript Promises:

  1. Wrap OnLoad в объекте Promise:

    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. Предполагая, что массивы images и sources, сделать массив обещаний:

    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, если какой-либо из изображений не загружается. И «wait» я имею в виду «добавить асинхронную задачу, которая будет выполняться только после обещаний».

  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

Смежные вопросы