所以,我有一些值的数组。我想将这些值发送到www.example.com。我必须每个请求只发送一个值。
我在node.js中使用http.request这个任务:
var myArr = [1,2,3,4,5,6,7,8,9,10,11,12];
function requestSender(data, callback)
{
var post = querystring.stringify({
data: data
});
var options = {
hostname: 'www.example.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = https.request(options, function(res)
{
res.setEncoding('utf-8');
res.on('data', function(data)
{
callback();
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(post);
req.end();
}
要逐个发送请求我正在使用函数,它接受一个函数数组并递归地添加下一个函数作为回调函数:
function stack(arr)
{
var newArr = arr.slice(1);
arr[0](function()
{
if (typeof newArr[0] == 'function') stack(newArr);
});
}
要将所有这些人员编成一个,我使用以下代码:
var functionsArr = [];
for (i in myArr)
{
functionsArr.push(function(callback)
{
var value = myArr[i];
requestSender(value, callback);
});
};
stack(functionsArr);
但实际上,这不起作用:所有请求都在1毫秒内发送,然后在回复响应时回调。但它不应该!我在http.request中放了 callback()(选项,回调)!!它是如何发生的?
所以我的问题是: 1)如何在node.js中严格逐个发送http请求? 2)为什么我的解决方案不起作用?
答案 0 :(得分:3)
答案 1 :(得分:2)
我看到我迟到了,但无论如何:
将函数放入循环或递归时,闭包中的变量在执行函数时计算,而不是在创建函数时计算。所以
for (i in [1, 2, 3]) {
setTimeout(function() {
console.log(i);
}, 1000);
}
返回
3
3
3
但
for (i in [1, 2, 3]) {
setTimeout(function(i) {
return function() {
console.log(i);
};
}(i), 1000);
}
会正确地给你
1
2
3
这就是为什么通常不建议将函数定义放在循环中。
无论如何,这里有更正的代码,请注意它console.logs所有内容的顺序正确:
var http = require('http');
var querystring = require('querystring');
var myArr = [1,2,3,4,5,6,7,8,9,10,11,12];
function requestSender(d, callback)
{
var post = querystring.stringify({
data: d
});
var options = {
hostname: 'www.example.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = http.request(options, function(res)
{
res.setEncoding('utf-8');
res.on('data', function(data)
{
console.log(d);
console.log(data);
callback();
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(post);
req.end();
}
function stack(arr)
{
var newArr = arr.slice(1);
arr[0](function(arg) {
return function() {
if (arg.length > 0)
stack(arg);
};
}(newArr));
}
var functionsArr = [];
for (i in myArr)
{
functionsArr.push(function(i) {
return function(callback) {
var value = myArr[i];
requestSender(value, callback);
};
}(i));
}
stack(functionsArr);
答案 2 :(得分:0)
您可以尝试这样的事情:
var myArr = [1,2,3,4,5,6,7,8,9,10,11,12];
var counter = -1;
function function requestSender(data)
{
var post = querystring.stringify({ data: data });
var options =
{
hostname: 'www.example.com',
port: 80,
path: '/upload',
method: 'POST'
};
var req = https.request(options, sendNextData);
req.on('error', function(e)
{
console.log('problem with request: ' + e.message);
});
req.write(post);
req.end();
}
function sendNextData()
{
if(++counter < myArr.length)
{
requestSender( myArr[ counter ] );
}
}
sendNextData();