c00000fd
c00000fd

Reputation: 22275

Chrome Extension callback functions and concurrency

I'm learning to code Chrome Extensions and I'm curious about passing parameters into asynchronous functions and a possible concurrency issue. Let me give you an example:

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);
}

So, lets assume that the first time my updateActiveTab() method is called with param1=1 and the call to chrome.tabs.query() takes a while. In the meantime, while chrome.tabs.query() is still being processed, my updateActiveTab() method is called again with param1=2. What would happen when the first call to chrome.tabs.query() returns and begins processing its callback function? Will param1 be 1 or 2?

I'm obviously looking to pass my param1 as 1, and 2, and so on, to its function's respective calls.

Upvotes: 0

Views: 679

Answers (1)

Julian - Intel
Julian - Intel

Reputation: 46

The short answer is that you will win. Read up on JavaScript closures to really understand what's going on here. I'll hit the highlights so you get the idea.

The reference to param1 inside of onUpdatingTab forces param1 into a closure. The closure keeps the value of param1 alive as long as it is needed by calls to inner functions. The scenario you describe will create two different closures, one for each call to onUpdatingTab.

Here's an example adapted from JavaScript: The Good Parts that illustrates this aspect of closures. This function takes an array of DOM nodes and adds an onclick handler that displays the ordinal of the node:

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);
    }
}

Each call to helper returns a function where the reference to "i" is bound to the closure for that helper call. Note the semantic distinction with code that doesn't use the helper, but just does this:

        nodes[i].onclick = function() { alert(i); }

Here "i" again binds to a closure, but it's the closure associated with the call to add_the_handlers, so clicking on each node displays the same value, which is the number of nodes not the ordinal. That's the last value assigned to "i".

Upvotes: 1

Related Questions