2011-04-13 9 views
5

Soy un nuevo desarrollador de nodejs, y creo que entiendo los diseños de nodejs.¿Por qué alguna biblioteca síncrona en nodejs se adhiere a la devolución de llamada?

Entiendo que alguna biblioteca relacionada con syscall debe ser asincrónica. Estos trabajos se pondrán en cola y se procesarán en un grupo de subprocesos diferente, y se notificarán mediante una devolución de llamada cuando finalice.

Sin embargo, no puedo entender por qué algunas bibliotecas no relacionadas con syscall están utilizando la devolución de llamada como método de comunicación. Por ejemplo, la biblioteca xml2js está escrita en Javascript, y aparentemente, no hay ninguna razón para que esta función parse devuelva el estado a través de la devolución de llamada. Puede devolver el resultado del procesamiento directamente, y se aumentará la legibilidad del código.

Mi pregunta es, ¿hay algún motivo por el que algunos diseñadores de bibliotecas nodej se adhieren a la comunicación basada en devolución de llamada en lugar de simplemente usar el valor devuelto?

+0

Consulte esto en relación con el problema xml2js https://github.com/Leonidas-from-XIV/node-xml2js/issues/47 – setec

Respuesta

5

No hay nada de malo con el estilo de devolución de llamada.

var return = doSomething(); 
... 

doSomething(function(return) { 
    ... 
}); 

Esta es la preferencia. Ambos son válidos. El primero solo parece "mejor" porque estás acostumbrado.

Una buena razón para esto último es que la API no tiene que cambiar cuando se cambia la biblioteca para que no sea bloqueante.

Las personas necesitan que se les recuerde que el nodo es una biblioteca IO de bajo nivel que no bloquea. Si vas a hacer algo como js2xml entonces claramente estás esperando que el nodo 0.6 estandarice la API de proceso secundario del trabajador web para que puedas enviar el trabajo pesado a un subproceso y hacer el trabajo duro real sin bloqueos.

Para hacer esto de una manera no bloqueante su API necesita ser asíncrona (o la necesita construir en el idioma).

3

Si no es asíncrono, no hay ninguna razón para usar una devolución de llamada para pasar el valor de retorno.

He visto algunas bibliotecas que usan devoluciones de llamada en lugar de devoluciones solo para devolver los errores, aunque, en mi opinión, usar throws es mejor y más limpio.

+0

En general, estoy de acuerdo. – BMiner

0

devoluciones de llamada puede ser útil en diversos escenarios, por ejemplo cuando se está iterando a través de alguna colección (que es encapsulado por alguna razón):

function Foo() { 
    this._data = [1, 2, 3, 4, 5]; 
} 

Foo.prototype.forEach = function(callback) { 
    var i, 
     len = this._data.length; 

    for(i = 0; i < len; i++) { 
     callback("Item number: " + this._data[i]); 
    } 
} 

var foo = new Foo(); 

foo.forEach(function(item) { 
    console.log(item); 
}); 
1

En realidad, en términos de la implementación LibXML analizador. ¿Estás seguro de que no hay ningún IO de nivel de sistema funcionando?

Piensa en el escenario donde el XML que analizas contiene una DTD o un Esquema. ¿Qué pasa con el procesamiento de XInclude que a menudo se realiza en XML-Parsers.

Aunque no hay una razón fundamental para tener una API que no utilice ninguna función de IO de bajo nivel para usar el estilo de devolución de llamada asíncrona, no siempre se sabe si no hay situaciones en las que IO realmente podría tener lugar .

Supongamos ahora que sabe que su analizador XML no hace ningún IO, porque no maneja la validación de XInclude y DTD/Schema. Si, por lo tanto, decide ir a la ruta del valor de retorno "tradicional", nunca podrá implementar XInclude Processing o Schema validation sin cambiar su API.

Con frecuencia, si está escribiendo una API, es mejor que vaya a la función de sincronización/devolución de llamada desde el principio, porque nunca sabe lo que quiere hacer más adelante.

Cuestiones relacionadas