[英]Functions within a loop using requirejs
我在使用requirejs在不同模塊之間的循環中調用函數時遇到問題。 循環中的函數調用駐留在模塊A中,並在模塊B中執行一個函數,該函數使用jQuery觸發Ajax請求。 循環的每次迭代都會觸發一個不同的請求,並將不同的參數傳遞給模塊B的函數,該模塊會觸發Ajax請求。 當執行Ajax請求的成功函數時,對於所有4個單獨的Ajax調用,我發現我的所有參數值始終是上一次進行的Ajax調用的值。
我已經進行了一些谷歌搜索,這聽起來像是在循環中執行函數時一個非常普遍的問題。 解決方法是將函數調用分解為一個不同的函數,從而創建一個不同的作用域。 由於我的循環和Ajax調用位於2個不同的模塊中,因此我認為這可以解決該問題,但是仍然存在。
我在其他堆棧溢出帖子中嘗試了一些解決方案,例如: JSlint錯誤“請勿在循環內創建函數”。 導致有關Javascript本身以及如何將參數傳遞給setTimeout調用中定義的匿名函數的問題? 沒有成功。 有人知道嗎
循環模塊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;
}
);
謝謝!
注意:我假設使用$poolOut.data('poolObj')
來查找傳遞給startMonitoring
的調用中傳遞的poolObj
實例,並且每次都會返回相同的實例。
您指出:“循環的每次迭代都會觸發一個不同的請求,並將不同的參數傳遞給模塊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){ ... }
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.