使用requirejs在循环内的函数

时间:2014-03-01 21:39:32

标签: javascript jquery ajax requirejs

我遇到了使用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 itselfHow 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;
}
);

谢谢!

1 个答案:

答案 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){ ... }
    }
};