2012-06-27 7 views
18

Entiendo lo básico acerca de la asincronía: las cosas no se ejecutan secuencialmente. Y entiendo que hay algo muy poderoso sobre eso ... supuestamente. Pero por mi vida no puedo entender el código. Echemos un vistazo al código Async Node.JS que HE ESCRITO ... pero que realmente no entiendo.Comprender el código asíncrono en los términos de Layman

function newuser(response, postData) { 
    console.log("Request handler 'newuser' was called."); 
    var body = '<html>' + 
     '<head>' + 
     '<meta http-equiv="Content-Type" content="text/html; ' + 
     'charset=UTF-8" />' + 
     '</head>' + 
     '<body>' + 
     '<form action=" /thanks" method="post">' + 
     '<h1> First Name </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<h1> Last Name </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<h1> Email </h1>' + 
     '<textarea name="text" rows="1" cols="20"></textarea>' + 
     '<input type="submit" value="Submit text" />' + 
     '</body>' + 
     '</html>'; 
    response.writeHead(200, { "Content-Type": "text/html" }); 
    response.write(body); 
    response.end(); 
} 

De dónde proceden de la respuesta de nuevo? ¿PostData? ¿Por qué no puedo definir una variable en esta "devolución de llamada" y luego usarla fuera de la devolución de llamada? ¿Hay alguna manera de que algunas cosas sean secuenciales y el resto del programa asincrónico?

Respuesta

41

No estoy seguro de dónde se está utilizando esta función, pero el punto de devolución de llamada es que los transfiera a alguna función que se ejecute de forma asíncrona; almacena su devolución de llamada, y cuando esa función se hace con lo que sea necesario, llamará a su devolución de llamada con los parámetros necesarios. Un ejemplo de adelante hacia atrás es probablemente el mejor.

Imagine que tenemos un marco, y en él hay una operación que se ejecuta durante mucho tiempo, obteniendo algunos datos de la base de datos.

function getStuffFromDatabase() { 
    // this takes a long time 
}; 

Como no queremos que se ejecute sincrónicamente, le permitiremos al usuario pasar una devolución de llamada.

function getStuffFromDatabase(callback) { 
    // this takes a long time 
}; 

Simularemos tomar un largo tiempo con una llamada a setTimeout; también pretendemos que obtuvimos algunos datos de la base de datos, pero solo codificaremos un valor de cadena.

function getStuffFromDatabase(callback) { 
    setTimeout(function() { 
    var results = "database data"; 
    }, 5000); 
}; 

Por último, una vez que tengamos los datos, vamos a llamada la devolución de llamada que se nos da por el usuario de la función del marco.

function getStuffFromDatabase(callback) { 
    setTimeout(function() { 
    var results = "database data"; 
    callback(results); 
    }, 5000); 
}; 

Como usuario del marco, usted haría algo como esto para utilizar la función:

getStuffFromDatabase(function(data) { 
    console.log("The database data is " + data); 
}); 

Por lo tanto, como se puede ver data (igual que response y postData en su ejemplo) vino de la función que pasa su devolución de llamada en; le proporciona esos datos cuando sabe cuáles deberían ser esos datos.

La razón por la que no puede establecer un valor en su devolución de llamada y usarla fuera de la devolución de llamada es porque la devolución de llamada en sí no ocurre hasta más adelante en el tiempo.

// executed immediately executed sometime in the future 
//  |     |  by getStuffFromDatabase 
//  v     v 
getStuffFromDatabase(function(data) { 
    var results = data; // <- this isn't available until sometime in the future! 
}); 

console.log(results); // <- executed immediately 

Cuando, la asignación de var results no ha ocurrido console.log las carreras todavía!

+0

Desde un punto técnico tienes razón, pero lo que te perdiste fue "por qué quieres hacer una devolución de llamada en primer lugar". Eso es lo que hace asincrónica tan importante. – jcolebrand

+3

No voy a decir que no leeré esto una o dos veces más, pero esa es probablemente la mejor explicación que se puede dar sin estar aquí físicamente, je. – PinkElephantsOnParade

+1

Creo que esta es una gran explicación para entender cómo funcionan las devoluciones de llamada, ¡gracias por ello! – wmock

6

tienes varias preguntas relacionadas aquí:

1) El poder de la asíncrono es ser capaz de hacer varias cosas a la vez sin bloquear el hilo principal. En nodo y js en general, esto se aplica particularmente a las solicitudes de archivos ajax. Esto significa que puedo activar varias llamadas asincrónicas para recuperar archivos y no bloquear el hilo principal mientras se procesa el contenido. Mi marco preferido es jQuery, que tiene $ .Deferred convenientes que envuelve y estandariza las llamadas asincrónicas para el uso de jQuery.

2) la respuesta y los datos posteriores vienen del método padre. No hay nada mágico aquí, es una llamada a función normal, por lo que los valores de estos se crean en otro lugar y pasan a esta invocación. Según la estructura de nodos que tenga, la firma exacta de su método cambiará.

3) Puede definir una variable global en su devolución de llamada si tiene un alcance adecuado. Sin embargo, parece que necesitas ayuda para saber qué alcance tiene. Estos son algunos enlaces

http://www.digital-web.com/articles/scope_in_javascript/

http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

4) Una vez que pasan asíncrono, nunca se puede volver atrás, sin embargo, mediante el aprovechamiento de la promesa y objetos diferidos como con jQuery Deferreds se puede esperar varios asyncs a complete antes de continuar su ejecución en otra asincronía. Deferreds son tus amigos.

http://api.jquery.com/category/deferred-object/

+0

De alguna manera me perdí esta muy buena respuesta la primera vez que busqué: +1 – PinkElephantsOnParade

+0

Maldición, lo hiciste. ¡Soy increíble! –

+2

Aplaudo su confianza – PinkElephantsOnParade

1

Parece que se está trabajando a través de la Node Beginner Book. Te animo a que estudies todo el libro, realmente es una excelente introducción. Si está tratando de entender mejor el Javascript, los videos de Douglas Crockford en YouTube son una gran descripción: 1, 2.

La pieza de código que ha publicado no tiene suficiente contexto para que realmente pueda ayudarlo. response es un parámetro que está pasando a su función, no proviene de postData. Si está trabajando con código de la manera en que lo sugiere el Node Beginner Book, probablemente esté transmitiendo una respuesta a su función newuser desde la función createServer, que es parte del módulo http que viene con Node.

No puede definir una variable en la devolución de llamada y luego usarla en la devolución de llamada porque Javascript tiene un alcance léxico. Aquí hay un Stack Overflow post sobre el tema del alcance de Javascript. El primer video de Doug Crockford que publiqué también tiene una gran explicación de las reglas de alcance de Javascript.

Javascript no es necesariamente asincrónico. Simplemente proporciona funciones anónimas que son cierres, que son una herramienta útil para implementar fácilmente la lógica asíncrona. De nuevo, el Node Beginner Book muestra un buen ejemplo de cómo escribir código sincrónico con Node (no es lo que desea), y luego lo reescribe para hacerlo asincrónico.

Cuestiones relacionadas