代码是否传递给顺序chrome.tabs.executeScript调用保证按顺序运行?

时间:2014-05-13 21:26:32

标签: google-chrome-extension

在我的测试中,代码似乎始终按照chrome.tabs.executeScript调用的顺序在目标选项卡中执行。例如,当我运行它时,我看到在目标选项卡的控制台中按顺序记录数字0..99:

for (var i = 0; i < 100; i++) {
  chrome.tabs.executeScript(150, {code: 'console.log(' + i + ')'}, function () {});
}

我想知道我是否可以依赖这种排序行为。如果是这样,我可以通过同步调用chrome.tabs.executeScript 10次来同时请求10个脚本执行 - 即使某些后续脚本依赖于某些早期脚本。

替代方案较慢:请求仅在当前脚本完成后(即从其回调)执行下一个脚本。这种方法的第二个缺点是我的扩展中的其他事件处理(例如,处理来自内容脚本的消息只是注入到选项卡中)可以与内容脚本执行交错,进一步减慢它的速度。

1 个答案:

答案 0 :(得分:3)

chrome.tabs.executeScript的相对执行顺序没有记录,但很可能你可以依赖它的订单。

在幕后,executeScript执行以下操作:

  1. JavaScript代码调用UI线程(source code)上的本机代码。
  2. 如果允许扩展名在选项卡中执行代码,则UI线程将带有执行详细信息的消息通过IPC(source codesource code)发送到渲染器进程
  3. 当渲染器收到消息(source code)时,它会执行网页中的代码(source code)。当脚本在所有页面中完成执行后,呈现器会将消息发送回扩展进程(source code)。
  4. 扩展进程收到消息,并调用回调(JavaScript)(source code)。
  5. 请注意,此流程中的所有内容都是同步:JavaScript是单线程的,因此代码会被同步处理。处理调用的本机代码也是同步运行的,IPC中的消息也是同步的。

    chrome.tabs.executeScript是异步的,因为它阻止扩展进程,直到选项卡中的代码完成(即在调用chrome.tabs.executeScript之后,它立即返回,准备执行代码中的下一个语句)。这很好,因为您不希望由于执行内容脚本中的alert对话框而导致您的扩展程序被冻结。

    这个答案是指主干上的代码(Chrome 36),但我相信它将来会保持准确,因为没有理由改变有意混合消息相对顺序的实现。混合消息的最现实的方法之一是使本机代码异步具有不同的执行路径(我认为这不会发生)。