2010-12-03 48 views
9

Necesito escribir una función en JavaScript, que devuelve un estado de llamar a una función asíncrona. Sin embargo, la persona que llama solo recibe el valor y no se debe proporcionar ninguna función de devolución de llamada. He intentado algo así como:Cómo bloquear las funciones asíncronas en JavaScript

function getState() { 
    var ret = null; 
    asyncCall("request", 
     function() { ret = "foo"; } // callback 
    ); 
    while (ret === null) 
     ; // block on the asynchronous call 
    return ret; 
} 

Sin embargo, el bucle nunca se va a acabar ...

¿Alguna idea? Gracias.

+2

¿Por qué quiere bloquear la llamada asincrónica en primer lugar? Hacer esto no tiene sentido. – Tomalak

+1

@Tomolak: porque es una llamada proporcionada por Firefox y no puedo cambiarla. Se espera que tome como mucho milisegundos, no quiero refactorizar todos mis otros códigos solo por esto. –

+0

¿Se puede publicar la función que llama a 'getState()'? – Tomalak

Respuesta

8

Creo que estás buscando StratifiedJS, http://stratifiedjs.org Le permite "orquestar" el código asíncrono exactamente igual que usted escribió, ten en cuenta que "escribe" como el código sincrónico NO bloqueará el resto de tu aplicación. Puede usarlo en cualquier lugar cargando la biblioteca apollo js.

Esta es la forma en que se vería en el estratificado JavaScript:

function getState() { 
    waitfor (var ret) { 
    // block on the asynchronous call 
    asyncCall("request", resume); 
    } 
    return ret; 
} 

por supuesto hay módulos/bibliotecas que acaba de hacer que se vea como esto: http://onilabs.com/modules#http

function getState() { 
    return http.get("request"); 
} 
+0

Aunque esto se basa en un analizador externo, parece la mejor solución aquí. –

+0

Lo hace. Pero en el gran esquema no agrega mucha sobrecarga. – tomg

0

¿Por qué no:

asyncCall("request", function() { 
    // here you can inspect the state 
}); 

Cuál es el punto de la función de contenedor?

Las funciones asíncronas funcionan de esta manera. Si desea bloquear la ejecución, a continuación, utilizar una llamada sincrónica:

var state = syncCall("request"); 
+0

Es algo así como una biblioteca, ya que estoy trabajando en varias plataformas. Y el resto del código necesita esperar esta información especial. No se proporciona una sustitución sincrónica. –

+0

@ryanli Luego, coloque el resto del código en la devolución de llamada. –

+1

@ Šime: ¿Quiere decir que las llamadas asincrónicas podrían infectar a todos los demás códigos que lo llamen? Solo quiero saber si hay una forma de bloquear estas llamadas asincrónicas. –

1

Lo mejor sería poner la lógica que desea que se llama a la función de devolución de llamada. ¿Hay alguna razón por la que no puedes hacer eso?

Usted podría utilizar setInterval para comprobar el resultado, sino que requiere una función de devolución de llamada, también ...

+0

Estoy escribiendo una extensión, no el documento normal JavaScript. El resto de la función depende de este estado, y lo único que se proporciona es una función asincrónica. –

1

A menos que no he entendido su pregunta, podría ver el evento ajaxStop() de jQuery - http://api.jquery.com/ajaxstop. Esto bloquea hasta que todas las llamadas ajax se hayan completado. Obviamente, esto requiere que todas sus llamadas asincrónicas se realicen a través de jQuery.

$(document).ajaxStop(function() { 
    // do your "ajax dependent" stuff here 
}); 
Cuestiones relacionadas