Node.JS:如何将变量传递给异步回调? [复制]
Posted
技术标签:
【中文标题】Node.JS:如何将变量传递给异步回调? [复制]【英文标题】:Node.JS: How to pass variables to asynchronous callbacks? [duplicate] 【发布时间】:2012-10-24 16:17:10 【问题描述】:我确定我的问题是由于对 node.js 中的异步编程缺乏了解,但这里是这样。
例如:我有一个要抓取的链接列表。当每个异步请求返回时,我想知道它用于哪个 URL。但是,大概是因为竞态条件,每个请求返回的 URL 都设置为列表中的最后一个值。
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links)
var url = links[link];
require('request')(url, function()
console.log(url);
);
预期输出:
http://google.com
http://yahoo.com
实际输出:
http://yahoo.com
http://yahoo.com
所以我的问题是:
-
如何将 url(按值)传递给回调函数?或
链接 HTTP 请求以便它们按顺序运行的正确方法是什么?或
我还缺少什么?
PS:对于 1. 我不想要一个检查回调参数的解决方案,而是一种通用的回调方法,它知道“从上面”的变量。
【问题讨论】:
【参考方案1】:您的 url
变量的范围不限于 for
循环,因为 javascript 仅支持全局和函数范围。因此,您需要为您的 request
调用创建一个函数范围,以使用立即函数在循环的每次迭代中捕获 url
值:
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links)
(function(url)
require('request')(url, function()
console.log(url);
);
)(links[link]);
顺便说一句,在循环中间嵌入 require
不是一个好习惯。它可能应该重写为:
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]);
【讨论】:
这与范围无关。这是关于闭包的。许多其他语言没有块作用域,但由于缺少闭包而没有遇到这个问题。 关键是,如果 JavaScript 确实支持块作用域,那么在 OP 代码的回调函数中对url
的闭包访问将起作用,因为循环的每次迭代都会得到自己的 url
变量(如在 C# 中)。
为简洁起见,require 就在其中,在我的代码中,所有 requires 都在开头。
如果我不在回调中使用forloop,它将返回未定义的url。【参考方案2】:
有关此问题的一般性讨论,请参阅 https://***.com/a/11747331/243639。
我会建议类似的东西
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));
【讨论】:
在 *** 上有很多更好的链接可以解释这个问题。例如:***.com/questions/3572480/…【参考方案3】:检查此blog。可以使用 .bind() 方法传递变量。在你的情况下,它会是这样的:
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));
【讨论】:
我更喜欢这种方法,因为它比在函数中包装东西更简洁。 这个不用forloop也能工作!以上是关于Node.JS:如何将变量传递给异步回调? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
Socket.io、Node.js:如何在 javascript.js 中将 javascript 变量传递给 mysql 查询?