After calling chrome.tabs.query, the results are not available

I'm creating (learning) an extension for Google Chrome.

To debug some code, I inserted console.log(), as follows:

var fourmTabs = new Array();
chrome.tabs.query({}, function (tabs) {
    for (var i = 0; i < tabs.length; i++) {
        fourmTabs[i] = tabs[i];
    }
});
for (var i = 0; i < fourmTabs.length; i++) {
    if (fourmTabs[i] != null)
        window.console.log(fourmTabs[i].url);
    else {
        window.console.log("??" + i);
    }
}

It's very simple code: get all tabs info into an array of my own, and print some things.

To check whether the code works as it should, I run the code. Here comes the problem:

  • When I use breakpoints (via the Developer tools), the code runs fine.
  • Without breakpoints, nothing is printed.

Any idea why?

Answers:

Answer

Your problem can be simplified to:

/*1.*/ var fourmTabs = [];
/*2.*/ chrome.tabs.query({}, function(tabs) {
/*3.*/     fourmTabs[0] = tabs[0];
/*4.*/ });
/*5.*/ console.log(fourmTabs[0]);

You expect that the fourmTabs array is updated (by line 3) when line 5 is reached.
That is wrong, because the chrome.tabs.query method is asynchronous.


In an attempt to make you understand the significance of the asynchronous aspect, I show a code snippet with the same structure as your code and a story.

/*1.*/ var rope = null;
/*2.*/ requestRope(function(receivedRope) {
/*3.*/     rope = receivedRope;
/*4.*/ });
/*5.*/ grab(rope);
  • At line 1, the presence of a rope is announced.
  • At lines 2-4, a callback function is created, which ought to be called by the requestRope function.
  • At line 5, you're going to grab the rope via the grab function.

When requestRope is implemented synchronously, there's no problem:
? You: "Hi, I want a rope. Please throw the rope"call the callback function" when you've got one."
? She: "Sure." throws rope
? You: Jumps and grabs rope - You manage to get at the other side, alive.

When requestRope is implemented asynchronously, you may have a problem if you treat it as synchronous:
? You: "Please throw a rope at me."
? She: "Sure. Let's have a look..."
? You: Jumps and attempts to grab rope Because there's no rope, you fall and die.
? She: Throws rope Too late, of course.


Now you've seen the difference between an asynchronously and synchronously implemented function, let's solve your original question:

var fourmTabs = new Array();
chrome.tabs.query({}, function (tabs) {
    for (var i = 0; i < tabs.length; i++) {
        fourmTabs[i] = tabs[i];
    }
    // Moved code inside the callback handler
    for (var i = 0; i < fourmTabs.length; i++) {
        if (fourmTabs[i] != null)
           window.console.log(fourmTabs[i].url);
        else {
            window.console.log("??" + i);
        }
    }
});
// <moved code inside callback function of chrome.tabs.query>

With breakpoints, your code works, because by the time that the second part of the code is reached, the callback has already been called.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.