javascript - sintaxis - Node.JS: ¿Cómo pasar variables a las devoluciones de llamada asincrónicas?
node js tutorial (3)
Esta pregunta ya tiene una respuesta aquí:
Estoy seguro de que mi problema se basa en una falta de comprensión de la programación asincrónica en node.js, pero aquí va.
Por ejemplo: tengo una lista de enlaces que quiero rastrear. Cuando se devuelve cada solicitud de asinción, quiero saber para qué URL está. Pero, presumiblemente debido a las condiciones de la carrera, cada solicitud regresa con la URL establecida en el último valor de la lista.
var links = [''http://google.com'', ''http://yahoo.com''];
for (link in links) {
var url = links[link];
require(''request'')(url, function() {
console.log(url);
});
}
Rendimiento esperado:
http://google.com
http://yahoo.com
Salida real:
http://yahoo.com
http://yahoo.com
Entonces mi pregunta es:
- ¿Cómo paso url (por valor) a la función de devolución de llamada? O
- ¿Cuál es la forma correcta de encadenar las solicitudes HTTP para que se ejecuten secuencialmente? O
- ¿Algo más que me estoy perdiendo?
PD: Para 1. No quiero una solución que examine los parámetros de la devolución de llamada sino una forma general de devolución de llamada que sepa sobre las variables ''desde arriba''.
Consulte https://.com/a/11747331/243639 para una discusión general sobre este tema.
Sugeriría algo como
var links = [''http://google.com'', ''http://yahoo.com''];
function createCallback(_url) {
return function() {
console.log(_url);
}
};
for (link in links) {
var url = links[link];
require(''request'')(url, createCallback(url));
}
Mira este blog . Se puede pasar una variable utilizando el método .bind (). En tu caso sería así:
var links = [''http://google.com'', ''http://yahoo.com''];
for (link in links) {
var url = links[link];
require(''request'')(url, function() {
console.log(this.urlAsy);
}.bind({urlAsy:url}));
}
Su variable url
no tiene alcance en el ciclo for
ya que JavaScript solo admite el ámbito global y funcional. Por lo tanto, debe crear un alcance de función para su llamada de request
para capturar el valor de la url
en cada iteración del ciclo mediante el uso de una función inmediata:
var links = [''http://google.com'', ''http://yahoo.com''];
for (link in links) {
(function(url) {
require(''request'')(url, function() {
console.log(url);
});
})(links[link]);
}
Por cierto, incorporar un require
en el medio del ciclo no es una buena práctica. Probablemente debería volver a escribirse como:
var request = require(''request'');
var links = [''http://google.com'', ''http://yahoo.com''];
for (link in links) {
(function(url) {
request(url, function() {
console.log(url);
});
})(links[link]);
}