我试图理解为什么我会看到以下内容:
我在for循环中触发了几个异步请求,然后只打印出响应。这是我正在做的非常简化的版本:
function getStuff(){
var singers = ['marley','matthews','johnson','buffett'];
for(lastname in singers){
var lastName = singers[lastname];
log("Making request for "+ singers[lastname]);
makeAsyncRequest(singers[lastname], function(response){
//this is the callback when the async request returns
log("RESPONSE - "+lastName+": "+response);
});
}
}
如果我同步运行代码(async:false),我每次都会得到以下结果:
Making request for marley
Making request for matthews
Making request for johnson
Making request for buffett
RESPONSE - marley: bob
RESPONSE - johnson: jack
RESPONSE - matthews: dave
RESPONSE - buffett: jimmy
当我异步运行时,我会看到如下结果。我知道答案可能会不按时返回。但我不明白的是,当他们回归故障时,为什么我会看到重复的值?例如,我可能会看到:
Making request for marley
Making request for matthews
Making request for johnson
Making request for buffett
RESPONSE - marley: bob
RESPONSE - johnson: dave
RESPONSE - matthews: dave
RESPONSE - buffett: jimmy
注意'dave'似乎被退回两次?我会理解是否切换了'jack'和'dave'的值,如下所示:
Making request for marley
Making request for matthews
Making request for johnson
Making request for buffett
RESPONSE - marley: bob
RESPONSE - johnson: dave
RESPONSE - matthews: jack
RESPONSE - buffett: jimmy
但是我不明白为什么回调中的“响应”参数似乎被设置为两次相同的值?我忽略了一些基本的东西吗?
感谢您的帮助!
答案 0 :(得分:1)
循环没有自己的范围。问题是,只有一个lastName
变量,当异步请求返回时,其内容并不总是您在迭代中分配给它的内容。
您应该阅读并理解how the scope in JavaScript works。
解决方案可能是循环中的另一个闭包:
function getStuff(){
var singers = ['marley','matthews','johnson','buffett'];
for( lastname in singers ) {
function( lastName ) {
log( "Making request for "+ lastName );
makeAsyncRequest( lastName, function(response) {
//this is the callback when the async request returns
log("RESPONSE - "+lastName+": "+response);
} );
}( singers[lastname] );
}
}
答案 1 :(得分:0)
尝试在for循环中保留姓氏的副本:
function getStuff()
{
var singers = ['marley','matthews','johnson','buffett'];
for(lastname in singers)
{
var currentName = lastname;
log("Making request for "+ singers[currentName]);
makeAsyncRequest(singers[lastname], function(response)
{
//this is the callback when the async request returns
log("RESPONSE - "+singers[currentName ]+": "+response);
});
}
}
答案 2 :(得分:-1)
你有一个竞争条件。响应处理程序中的歌手[name]值完全取决于for()循环所处的状态。一旦执行异步请求,如果任何请求被延迟,则完全有可能失去同步(net.burp) ,慢服务器等...)。
答案 3 :(得分:-1)
在这种情况下,远程休息服务需要基本身份验证。我每次通过循环时都会发送不同的用户名和密码。我终于意识到基本的身份验证凭据在服务器端缓存了。
在服务器端,如果服务找到名为JSESSIONID的有效cookie,则会忽略http请求标头中的Basic Auth用户名和密码。
所以,解决方案是使用Jquery cookie插件并确保为每个请求删除JSESSIONID,如下所示:
$.cookie('JSESSIONID', null {path: '/pathToCookie'});