我正在学习编写 Chrome 扩展程序代码,并且对将参数传递到异步函数以及可能的并发问题感到好奇。让我举个例子:
function updateActiveTab(param1)
{
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
onUpdatingTab(tabs[0].id, param1);
});
}
function onUpdatingTab(tabID, param1)
{
console.log("Tag ID=" + tabID + ", param=" + param1);
}
所以,让我们假设我第一次 updateActiveTab()
方法用 param1=1
调用并调用 chrome.tabs.query()
需要一段时间。与此同时,同时chrome.tabs.query()
还在处理中,我的updateActiveTab()
方法再次被调用 param1=2
。第一次调用 chrome.tabs.query()
时会发生什么返回并开始处理其回调函数?会param1
是1
或2
?
我显然希望通过我的param1
如 1 和 2 等,分别调用其函数。
最佳答案
简短的回答是你会赢。阅读 JavaScript 闭包以真正了解这里发生的事情。我将突出重点,以便您明白。
onUpdatingTab 内部对 param1 的引用强制 param1 进入闭包。只要调用内部函数需要,闭包就会使 param1 的值保持事件状态。您描述的场景将创建两个不同的闭包,每次调用 onUpdatingTab 一个闭包。
下面是一个改编自 JavaScript 的示例:The Good Parts,它说明了闭包的这一方面。此函数采用 DOM 节点数组并添加一个显示节点序号的 onclick 处理程序:
function add_the_handlers = function (nodes) {
var helper = function(i) {
return function(e) { alert(i); };
};
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = helper(i);
}
}
每次调用 helper 都会返回一个函数,其中对“i”的引用绑定(bind)到该 helper 调用的闭包。请注意与不使用帮助器但仅执行以下操作的代码之间的语义区别:
nodes[i].onclick = function() { alert(i); }
这里“i”再次绑定(bind)到一个闭包,但它是与调用 add_the_handlers 关联的闭包,因此单击每个节点会显示相同的值,这是节点数而不是序数。这是分配给“i”的最后一个值。
关于javascript - Chrome扩展回调函数和并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25672332/