【发布时间】:2014-11-07 15:34:03
【问题描述】:
我在 Node.js 中使用“请求”异步获取大量数据。
首先,请求回调不包含原始请求发布参数(这太可怕了),所以我必须自己通过向请求添加 x-header 来实现这一点(因为原始请求的标头在回调响应)。
但是,请求标头通常与响应结果不匹配。 IE。我快速连续请求两个 URL,回调会将它们混合在一起。它将声称一个请求的请求标头属于另一个请求的结果。
var getActiveGames = function() {
console.log(activeGamePlayer);
if (activeGamePlayer >= Object.keys(players).length-1) {
activeGamePlayer = 0;
}
var player = Object.keys(players)[activeGamePlayer];
var ign = players[player].ign;
if (ign) {
request.post({
headers: {
'content-type' : 'application/x-www-form-urlencoded',
'x-summoner' : player
},
url: URL,
body: 'userName=' + ign + '&force=true'
}, function(error, response, body){
if (!error) {
if (response.statusCode == 200) {
jsdom.env(body, ['http://code.jquery.com/jquery.js'], function(err, window) {
if (window.jQuery) {
activeGamePlayer += 1;
var $ = window.jQuery;
var isPlaying = $('div:first').hasClass('SpectatorBig');
//var playerID = response.client._httpMessage._headers['x-summoner']; //doesn't work due to request and response headers mismatch
var playername = isPlaying ? $('tr.mine .summonerName').html() : $('div.nBoxContent b').html();
if (playername) {
var playerID;
for (var p in players) {
if (players[p].ign) {
if (players[p].ign == playername) {
playerID = p;
}
}
}
if (isPlaying) {
var champion = $('tr.mine div.__spc32').removeClass('__spc32 img').attr('class');
champion = champion.replace('__spc32-', '');
var gameURL = $('div.Spectate a').attr('href');
var timestamp;
if ($('._countdown').length) {
timestamp = $('._countdown').attr('data-timestamp');
} else {
timestamp =$('._timeago').attr('data-datetime');
}
players[playerID].activeGame = {
'timestamp' : timestamp,
'champion' : champion,
'finished' : false,
};
} else {
if (players[playerID].hasOwnProperty('activeGame')) {
players[playerID].activeGame.finished = true;
// make sure no game is in players json object
}
}
} else {
console.log ("Error: Faulty data from op.gg");
faultyIGN = Object.keys(players).length;
}
} else {
console.log("Error: No jQuery object in jsdom body.");
}
});
} else {
console.log("GetActiveGame: Status Code not 200");
}
} else {
console.log("GetActiveGame: " + error);
}
setTimeout(getActiveGames, 100);
});
} else {
//no ign
activeGamePlayer += 1;
setTimeout(getActiveGames, 100);
}
}
问题在于此实例中的响应对象包含不正确的信息。它包含的请求和响应信息不匹配,它们来自不同的请求和响应。
【问题讨论】:
-
您能否提供一个简化的、完整的示例来重现特定问题?另外,如果您需要访问您发送的正文,为什么不直接将其拉出到一个变量中,然后您也可以在回调中访问它?
-
回调似乎弄乱了范围。如果我将其中几个放在 for 循环中并设置变量,它们将在回调中混淆(即,在循环的一个实例中设置的变量将可以在不同的循环实例回调的回调中访问),具体取决于时间。
-
您总是可以在 for 循环中使用闭包来捕获主体的当前值,这将解决该特定问题。
-
但是 for 循环的每个实例本身已经是一个闭包,不是吗?
-
不,JavaScript 中的控制结构不是闭包。
标签: javascript node.js asynchronous callback request