ejemplo simple de devoluciones de llamada de nodeJs


120

¿Alguien puede darme un ejemplo simple de devoluciones de llamada de nodeJs? Ya he buscado lo mismo en muchos sitios web pero no puedo entenderlo correctamente. Por favor, dame un ejemplo simple.

getDbFiles(store, function(files){
    getCdnFiles(store, function(files){
    })
})

Quiero hacer algo como eso...


un ejemplo sobre cómo escribir una función que toma una devolución de llamada como argumento?
Gntem

sí, algo así, cualquier ejemplo simple que me ayude a entenderlo.
Bhushan Goel

2
Una devolución de llamada es una función que pasa como parámetro a otra función ... Google pls -> "callback javascript" -> primer resultado
Gabriel Llamas

Respuestas:


198
var myCallback = function(data) {
  console.log('got data: '+data);
};

var usingItNow = function(callback) {
  callback('get it?');
};

Ahora abra el nodo o la consola del navegador y pegue las definiciones anteriores.

Finalmente utilícelo con la siguiente línea:

usingItNow(myCallback);

Con respecto a las convenciones de errores de estilo de nodo

Costa preguntó cómo se vería esto si cumpliéramos las convenciones de devolución de llamada de error de nodo.

En esta convención, la devolución de llamada debe esperar recibir al menos un argumento, el primer argumento, como un error. Opcionalmente tendremos uno o más argumentos adicionales, según el contexto. En este caso, el contexto es nuestro ejemplo anterior.

Aquí reescribo nuestro ejemplo en esta convención.

var myCallback = function(err, data) {
  if (err) throw err; // Check for the error and throw if it exists.
  console.log('got data: '+data); // Otherwise proceed as usual.
};

var usingItNow = function(callback) {
  callback(null, 'get it?'); // I dont want to throw an error, so I pass null for the error argument
};

Si queremos simular un caso de error, podemos definir usingItNow así

var usingItNow = function(callback) {
  var myError = new Error('My custom error!');
  callback(myError, 'get it?'); // I send my error as the first argument.
};

El uso final es exactamente el mismo que el anterior:

usingItNow(myCallback);

La única diferencia en el comportamiento dependería de la versión de usingItNowque hayas definido: la que alimenta un "valor de verdad" (un objeto Error) a la devolución de llamada para el primer argumento, o la que lo alimenta como nulo para el argumento de error. .


Entonces, ¿cómo se ve esto con el error como la primera convención de parámetros?
Costa

113

Una función de devolución de llamada es simplemente una función que se pasa a otra función para que la función pueda llamarla en un momento posterior. Esto se ve comúnmente en las API asincrónicas ; la llamada a la API regresa inmediatamente porque es asincrónica, por lo que le pasa una función que la API puede llamar cuando termine de realizar su tarea asincrónica.

El ejemplo más simple que se me ocurre en JavaScript es la setTimeout()función. Es una función global que acepta dos argumentos. El primer argumento es la función de devolución de llamada y el segundo argumento es un retraso en milisegundos. La función está diseñada para esperar la cantidad de tiempo adecuada y luego invocar su función de devolución de llamada.

setTimeout(function () {
  console.log("10 seconds later...");
}, 10000);

Es posible que haya visto el código anterior antes, pero simplemente no se dio cuenta de que la función que estaba pasando se llamaba función de devolución de llamada. Podríamos reescribir el código anterior para hacerlo más obvio.

var callback = function () {
  console.log("10 seconds later...");
};
setTimeout(callback, 10000);

Las devoluciones de llamada se utilizan en todas partes en Node porque Node se construye desde cero para ser asincrónico en todo lo que hace. Incluso cuando habla con el sistema de archivos. Es por eso que muchas de las API internas de Node aceptan funciones de devolución de llamada como argumentos en lugar de devolver datos que puede asignar a una variable. En su lugar, invocará su función de devolución de llamada, pasando los datos que deseaba como argumento. Por ejemplo, puede usar la fsbiblioteca de Node para leer un archivo. El fsmódulo expone dos funciones API únicas: readFiley readFileSync.

La readFilefunción es asincrónica, mientras readFileSyncque obviamente no lo es. Puede ver que tienen la intención de que use las llamadas asíncronas siempre que sea posible, ya que las llamaron readFiley en readFileSynclugar de readFiley readFileAsync. A continuación, se muestra un ejemplo del uso de ambas funciones.

Sincrónico:

var data = fs.readFileSync('test.txt');
console.log(data);

El código anterior bloquea la ejecución del hilo hasta que todo el contenido de test.txtse lee en la memoria y se almacena en la variable data. En el nodo, esto generalmente se considera una mala práctica. Sin embargo, hay ocasiones en las que es útil, como cuando se escribe un pequeño guión rápido para hacer algo simple pero tedioso y no te importa mucho ahorrar cada nanosegundo de tiempo que puedas.

Asincrónico (con devolución de llamada):

var callback = function (err, data) {
  if (err) return console.error(err);
  console.log(data);
};
fs.readFile('test.txt', callback);

Primero creamos una función de devolución de llamada que acepta dos argumentos erry data. Un problema con las funciones asíncronas es que se vuelve más difícil capturar errores, por lo que muchas API de estilo de devolución de llamada pasan errores como primer argumento de la función de devolución de llamada. Es una buena práctica comprobar si errtiene un valor antes de hacer cualquier otra cosa. Si es así, detenga la ejecución de la devolución de llamada y registre el error.

Las llamadas síncronas tienen una ventaja cuando se lanzan excepciones porque simplemente puede capturarlas con un try/catchbloqueo.

try {
  var data = fs.readFileSync('test.txt');
  console.log(data);
} catch (err) {
  console.error(err);
}

En las funciones asincrónicas no funciona de esa forma. La llamada a la API regresa de inmediato, por lo que no hay nada que detectar con try/catch. Las API asincrónicas adecuadas que utilizan devoluciones de llamada siempre detectarán sus propios errores y luego pasarán esos errores a la devolución de llamada donde puede manejarlo como mejor le parezca.

Sin embargo, además de las devoluciones de llamada, hay otro estilo popular de API que se usa comúnmente llamado promesa. Si desea leer sobre ellos, puede leer la publicación completa del blog que escribí en función de esta respuesta aquí .


3
una entrega bastante elaborada pero concisa del concepto; para un iniciador de node.js como yo ...
kmonsoor

3
+1 para proporcionar mucho contexto. No solo el aspecto de las funciones de devolución de llamada, sino también qué son, por qué se usan y por qué se usan mucho. Realmente útil para un principiante.
Azurespot

1
¡Excelente! ¡Esto podría ser una publicación en sí misma!
Pablo Glez

1
Lo es , e incluye una segunda parte sobre promesas;)
Chev

1
¡Esta es una explicación mucho mejor que la respuesta aceptada! Me encantaría que todas las respuestas aceptadas aquí en SO sean así, no solo un fragmento de código que resuelve el problema, sino también el POR QUÉ y el CÓMO resuelve el problema. Básicamente, esta respuesta y devolución de llamada le darían una comprensión bastante sólida de lo que es la devolución de llamada.
RusI

10

Aquí hay un ejemplo de cómo copiar un archivo de texto con fs.readFiley fs.writeFile:

var fs = require('fs');

var copyFile = function(source, destination, next) {
  // we should read source file first
  fs.readFile(source, function(err, data) {
    if (err) return next(err); // error occurred
    // now we can write data to destination file
    fs.writeFile(destination, data, next);
  });
};

Y ese es un ejemplo de uso de la copyFilefunción:

copyFile('foo.txt', 'bar.txt', function(err) {
  if (err) {
    // either fs.readFile or fs.writeFile returned an error
    console.log(err.stack || err);
  } else {
    console.log('Success!');
  }
});

El patrón común de node.js sugiere que el primer argumento de la función de devolución de llamada es un error. Debe utilizar este patrón porque todos los módulos de flujo de control se basan en él:

next(new Error('I cannot do it!')); // error

next(null, results); // no error occurred, return result

2
¿lo que sigue? ¿Cuál es la variable resultados = cómo se llama?
The Nomadic Coder

3
@SemicolonWarrier un puntero para mí y para otros: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor

7

Pruebe este ejemplo tan simple como pueda leer, simplemente copie save newfile.js do node newfile para ejecutar la aplicación.

function myNew(next){
    console.log("Im the one who initates callback");
    next("nope", "success");
}


myNew(function(err, res){
    console.log("I got back from callback",err, res);
});

3

estamos creando una función simple como

callBackFunction (data, function ( err, response ){
     console.log(response)
}) 

// callbackfunction 
function callBackFuntion (data, callback){
    //write your logic and return your result as
callback("",result) //if not error
callback(error, "") //if error
}

1
const fs = require('fs');

fs.stat('input.txt', function (err, stats) {
    if(err){
        console.log(err);
    } else {
        console.log(stats);
        console.log('Completed Reading File');
    }
});

'fs' es un módulo de nodo que le ayuda a leer archivos. La función de devolución de llamada se asegurará de que su archivo llamado 'input.txt' se lea completamente antes de ejecutarse. La función fs.stat () es obtener información del archivo como el tamaño del archivo, la fecha de creación y la fecha de modificación.


1

//delay callback function
function delay (seconds, callback){
    setTimeout(() =>{
      console.log('The long delay ended');
      callback('Task Complete');
    }, seconds*1000);
}
//Execute delay function
delay(1, res => {  
    console.log(res);  
})


0

A callbackes una función que se pasa como parámetro a Higher Order Function( wikipedia ). Una implementación simple de una devolución de llamada sería:

const func = callback => callback('Hello World!');

Para llamar a la función, simplemente pase otra función como argumento a la función definida.

func(string => console.log(string));

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.