Después de llamar a chrome.tabs.query, los resultados no están disponibles

Estoy creando (aprendiendo) una extensión para Google Chrome.

Para depurar algún código, console.log() , de la siguiente manera:

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

Es un código muy simple: obtenga toda la información de tabs en una matriz propia e imprima algunas cosas.

Para verificar si el código funciona como debería, ejecuto el código. Aquí viene el problema:

  • Cuando uso puntos de interrupción (a través de las herramientas de desarrollo), el código funciona bien.
  • Sin puntos de interrupción, no se imprime nada.

¿Alguna idea de por qué?

Su problema se puede simplificar a:

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

fourmTabs que la matriz fourmTabs se actualice (por la línea 3) cuando se scope la línea 5.
Eso está mal , porque el método chrome.tabs.query es asíncrono .


En un bash por hacerle comprender el significado del aspecto asynchronous, muestro un fragment de código con la misma estructura que su código y una historia.

 /*1.*/ var rope = null; /*2.*/ requestRope(function(receivedRope) { /*3.*/ rope = receivedRope; /*4.*/ }); /*5.*/ grab(rope); 
  • En la línea 1, se anuncia la presencia de una string.
  • En las líneas 2 a 4, se crea una function de callback , que debe ser llamada por la function requestRope .
  • En la línea 5, agarrarás la string mediante la function de grab .

Cuando requestRope se implementa de forma sincronizada , no hay problema:
Tú: "Hola, quiero una string. Por favor, tira la string ", llama a la function de callback " cuando tengas una".
Ella: "Claro". tira la string
Tú: Salta y agarra la string : logras llegar al otro lado, vivo .

Cuando requestRope se implementa de forma asincrónica , puede tener un problema si lo trata como sincrónico:
Usted: "Por favor, arrojame una string".
Ella: "Claro. Echemos un vistazo …"
Tú: saltas e intenta agarrar la string. Porque no hay string, te caes y mueres.
Ella: lanza una string Demasiado tarde, por supuesto.


Ahora que ha visto la diferencia entre una function implementada de forma asincrónica y sincrónica, resuelvamos su pregunta original:

 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> 

Con los puntos de interrupción, su código funciona, porque cuando se llega a la segunda parte del código, ya se ha llamado a la callback.