我遇到了使用requirejs在不同模块的循环内调用函数的问题。循环中的函数调用驻留在模块A中,并在模块B中执行一个函数,该函数使用jQuery触发Ajax请求。循环的每次迭代都会触发一个不同的请求,并将不同的参数传递给模块B的函数,该函数将触发Ajax请求。当Ajax请求的成功函数执行时,我发现所有4个单独的Ajax调用都是我的所有参数值始终是最后一次调用Ajax的值。
我做了一些谷歌搜索,听起来这是在循环中执行函数时非常常见的问题。修复往往是将函数调用分解为不同的函数,创建不同的范围。由于我的循环和Ajax调用是在2个不同的模块中,我认为这将解决该问题,但它仍然存在。
我在其他堆栈溢出帖子中尝试了一些解决方案,例如: JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself和How to pass parameter to an anonymous function defined in the setTimeout call?没有成功。有人有任何想法吗?
循环模块A的示例代码:
define(["mpos"],
function(mpos){
var monitor = {
startMonitoring : function(poolObj){
// Start Monitoring
$.each(mpos.msgs, function(action,callback){
poolObj.action = action;
mpos.sendApiRequest(poolObj,action,callback);
});
}
};
return monitor;
}
);
Ajax模块B的示例代码 - 该模块在模块A中引用为mpos
define(["mule","constants"],
function(mule,constants){
var mpos = {
sendMessage : function(postData,callback,$poolOut){
return $.ajax({
'type':'post',
'url':constants.URLS.proxy,
'data':{'url':postData},
success : function(data){
// if we have $poolOut we know this is a mpos call
if($poolOut != undefined){
var keys = Object.keys(data);
// add poolOut to data
data.poolOut = $poolOut;
var poolObj = $poolOut.data('poolObj');
if(poolObj){
var action = poolObj.action;
console.log(poolObj,action);
if(action){
if(action == "getuserstatus"){
mule.registerPool(poolObj);
}
} else {
log.error("No action on poolObj while attempting to calculate the need for a registerPool call");
}
}
}
// parse data
callback.apply(this, data);
},
error : function(x,h,r){ ... },
dataType : 'json'
});
},
sendApiRequest : function(poolObj,action,callback){
var url = poolObj.url + '&page=api&action=' + action;
var $poolOut = constants.cache.monitorOutput.find('.pool-out.' + poolObj.id);
var dfd = mpos.sendMessage(url,callback,$poolOut);
$.when(dfd).always(function(){
var refreshTimer = setTimeout(function(){
if(constants.state.monitorEnabled){
mpos.sendApiRequest(poolObj, action, callback);
}
}, poolObj.refreshRate);
});
},
msgs : {
"getuserstatus" : function(data){ ... },
"getpoolstatus" : function(data){ ... },
"getuserworkers" : function(data){ ... },
"getuserbalance" : function(data){ ... }
}
};
return mpos;
}
);
谢谢!
答案 0 :(得分:1)
注意:我假设$poolOut.data('poolObj')
用于查找poolObj
调用中传递的startMonitoring
实例,并且每次都会返回相同的实例。
您声明,“循环的每次迭代都会触发一个不同的请求,并将不同的参数传递给模块B的函数,该函数将触发Ajax请求。”
此声明不正确。每次迭代都会触发一个不同的请求,第一个参数poolObj
在每次迭代中都是相同的。
在.each
次迭代中,在每次调用poolObj.action
之前,您都会覆盖sendApiRequest
的值。
在AJAX成功处理程序中,可能在所有迭代完成后调用,poolObj.action
的值将具有您在上一次迭代中设置的值。
要解决此问题,我认为您还需要将action
作为参数传递给sendMessage
,以便为每个函数调用在闭包中存储单独的值。
var mpos = {
sendMessage : function(postData,action,callback,$poolOut){
return $.ajax({
'type':'post',
'url':constants.URLS.proxy,
'data':{'url':postData},
success : function(data){
// if we have $poolOut we know this is a mpos call
if($poolOut != undefined){
var keys = Object.keys(data);
// add poolOut to data
data.poolOut = $poolOut;
var poolObj = $poolOut.data('poolObj');
if(poolObj){
// action is not guaranteed to be the same as poolObj.action here,
// since poolObj.action may have changed since this function was first called
console.log(poolObj,action);
if(action){
if(action == "getuserstatus"){
mule.registerPool(poolObj);
}
} else {
log.error("No action on poolObj while attempting to calculate the need for a registerPool call");
}
}
}
// parse data
callback.apply(this, data);
},
error : function(x,h,r){ ... },
dataType : 'json'
});
},
sendApiRequest : function(poolObj,action,callback){
var url = poolObj.url + '&page=api&action=' + action;
var $poolOut = constants.cache.monitorOutput.find('.pool-out.' + poolObj.id);
var dfd = mpos.sendMessage(url,action,callback,$poolOut);
$.when(dfd).always(function(){
var refreshTimer = setTimeout(function(){
if(constants.state.monitorEnabled){
mpos.sendApiRequest(poolObj, action, callback);
}
}, poolObj.refreshRate);
});
},
msgs : {
"getuserstatus" : function(data){ ... },
"getpoolstatus" : function(data){ ... },
"getuserworkers" : function(data){ ... },
"getuserbalance" : function(data){ ... }
}
};