15

Estoy creando (aprendiendo) una extensión para Google Chrome.Después de llamar a chrome.tabs.query, los resultados no están disponibles

para depurar un cierto código, he insertado 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); 
    } 
} 

su código muy simple: obtener toda la información pestañas en una matriz de mi propia e imprimir algunas cosas.

Para comprobar 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é?

+0

gracias por los enlaces, entiendo el problema, pero no estoy seguro de cómo solucionarlo. ¿Puedes dar algunas ideas? o puede que tenga algún código de muestra sobre cómo lo hará? – samy

+0

La clave es "Reescribir correctamente el código, para implementar correctamente el aspecto ** asincrónico" (citado [mi respuesta] (http://stackoverflow.com/a/10955980)). ¿Qué parte no entiendes? ¿Conoces la diferencia entre la programación sincrónica y la asíncrona? –

+0

sigo aprendiendo javascript y supongo que todavía no llegué a esta parte. ¿Me puede dar algunas refrences, o un código simple en el área de extensión de cromo? – samy

Respuesta

79

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

Se espera que la matriz fourmTabs se actualiza (por línea 3) cuando se alcanza la línea 5.
Eso es incorrecto, porque el método chrome.tabs.query es asincrónico.


En un intento de hacer que usted entiende la importancia del aspecto asíncrono, se muestra un fragmento de código con la misma estructura que el 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, la presencia de una cuerda se anuncia.
  • En las líneas 2-4, se crea una función de devolución de llamada , que debe llamarse mediante la función requestRope.
  • En la línea 5, agarrarás la cuerda a través de la función grab.

Cuando requestRope se implementa sincrónicamente, no hay problema:
  Usted: ". Hola, quiero una cuerda favor tirar la cuerda'llamar a la función de devolución de llamada' cuando se tiene uno."
  Ella: "Claro". tiros cuerda
  Usted: saltos y agarra la cuerda - Usted maneja conseguir en el otro lado, vivos.

Cuando requestRope se implementa de forma asíncrona , es posible que tenga un problema si lo trata como síncrono:
  Usted: "Por favor, lanza una cuerda en mí."
  Ella: "Claro.Vamos a echar un vistazo ..."
  usted: Los saltos y los intentos de agarrar la cuerda Porque no hay cuerda, se cae y mueren
  Ella:. Lanza cuerda Demasiado tarde, por supuesto

.

Ahora que usted ha visto la diferencia entre una función implementada de forma asíncrona y síncrona, vamos a resolver 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 puntos de interrupción, su código funciona, porque para cuando se alcanza la segunda parte del código, ya se ha llamado a la devolución de llamada.

+1

wow! gracias! ahora, entiendo que tengo que esperar, antes de obtener los datos en mi Arry. el ejemplo de la cuerda es genial, pero, ¿puedes mostrarme (si no es tan difícil) cómo te asegurarás de que me arroje la cuerda antes de saltar a mi muerte? – samy

+3

@samy Simplemente salte * después de * recibir la cuerda. La "lógica de salto" debe adjuntarse a la función de devolución de llamada. He agregado el código para tu caso al final de la respuesta, espero que lo entiendas ahora :) –

+2

ohhhh, veo la diferencia ahora. ahora lo entiendo! ¡¡Muchas gracias!! por tomarse el tiempo y hacerme entender este tema :) – samy

Cuestiones relacionadas