Javascript 如何在ajax回调中保留变量?

Javascript 如何在ajax回调中保留变量?,javascript,jquery,ajax,asp.net-mvc,asynchronous,Javascript,Jquery,Ajax,Asp.net Mvc,Asynchronous,我编写了一些javascript来运行一系列“模块”。对于每个模块,它进行一个ajax调用,获取模块的html,并将模块转储到页面布局的两列之一 var modules = [ { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' }, { name: 'Grid', title: 'Contacts', column: 'right' } { name: 'Filters', title:

我编写了一些javascript来运行一系列“模块”。对于每个模块,它进行一个ajax调用,获取模块的html,并将模块转储到页面布局的两列之一

var modules = [
    { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' },
    { name: 'Grid', title: 'Contacts', column: 'right' }
    { name: 'Filters', title: 'Filters', column: 'left' }
],
modulesUrl = '/Modules/';

for (var count = 0; count < modules.length; count++) {
    var module = modules[count];

    // Get module HTML.
    $.ajax({
        url: modulesUrl + module.name,
        success: function (moduleHtml) {

            // Append module HTML to appropriate element.
            $('#' + module.column + 'Column').append(moduleHtml);

            // Custom event to trigger the module to load its data.
            var initializeModuleEvent = $.Event('initialize' + module.name);
            initializeModuleEvent.firstLoad = true;
            $(document).trigger(initializeModuleEvent);

        }
    });
}
var模块=[
{name:'ExchangeStatus',title:'Exchange Status',column:'left'},
{name:'Grid',title:'Contacts',column:'right'}
{name:'Filters',title:'Filters',column:'left'}
],
模块URL='/Modules/';
对于(var count=0;count

问题是for循环创建了一个竞争条件。在ajax回调中,
module.column
几乎总是最后一个模块的值,因为for循环在ajax回调返回之前很久就结束了。如何维护模块变量,以便每个回调都处理相应的模块?目前,所有三个模块都位于左列,因为循环中的最后一个模块位于左列。

您可以尝试创建一个额外的作用域来传递
模块:

for (var count = 0; count < modules.length; count++) {
    var module = modules[count];

    (function(module) {
      $.ajax({
        ...
      })
    }(module));
那会有帮助的

for (var count = 0; count < modules.length; count++) {
    var module = modules[count];

    (function (module) {
        // Get module HTML.
        $.ajax({
            url: modulesUrl + module.name,
            success: function (moduleHtml) {

                // Append module HTML to appropriate element.
                $('#' + module.column + 'Column').append(moduleHtml);

                // Custom event to trigger the module to load its data.
                var initia`enter code here`lizeModuleEvent = $.Event('initialize' + module.name);
                initializeModuleEvent.firstLoad = true;
                $(document).trigger(initializeModuleEvent);

            }
        });
    })(module)
}
for(var count=0;count
将您的成功回调修改为:

$.ajax({
    url: modulesUrl + module.name,
    success: (function (module) {
        return function (moduleHtml) {
            // Append module HTML to appropriate element.
            $('#' + module.column + 'Column').append(moduleHtml);

            // Custom event to trigger the module to load its data.
            var initializeModuleEvent = $.Event('initialize' + module.name);
            initializeModuleEvent.firstLoad = true;
            $(document).trigger(initializeModuleEvent);
        };
    }(module));
});
这将为相应的
模块
变量值创建一个新范围


无需在此处包装整个
ajax
调用。

试试这种方法,告诉我它是否有效

for (var n = 0; n < modules.length; n++) {
(function () {
    var i = n;
        var module = modules[i];

        // Get module HTML.
        $.ajax({
            url: modulesUrl + module.name,
            success: function (moduleHtml) {

                // Append module HTML to appropriate element.
                $('#' + module.column + 'Column').append(moduleHtml);

                // Custom event to trigger the module to load its data.
                var initializeModuleEvent = $.Event('initialize' + module.name);
                initializeModuleEvent.firstLoad = true;
                $(document).trigger(initializeModuleEvent);

            }
        });
    } ());
}
for(var n=0;n
不要使用for循环,而是使用jquery的each。。这将解决问题

var modules = [
    { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' },
    { name: 'Grid', title: 'Contacts', column: 'right' }
    { name: 'Filters', title: 'Filters', column: 'left' }
],
modulesUrl = '/Modules/';

$(modules).each( function(index, elem)
{
    var module = elem;

    // Get module HTML.
    $.ajax({
        url: modulesUrl + module.name,
        success: function (moduleHtml) {

            // Append module HTML to appropriate element.
            $('#' + module.column + 'Column').append(moduleHtml);

            // Custom event to trigger the module to load its data.
            var initializeModuleEvent = $.Event('initialize' + module.name);
            initializeModuleEvent.firstLoad = true;
            $(document).trigger(initializeModuleEvent);

        }
    });
}
}
);

非常感谢!我为自己没有想到使用闭包而感到愚蠢,但我真的很感激:这不是唯一的选择,而是最明显的选择。你可以使用
forEach
,如果你想的话,可以忘记闭包。我不知道javascript有一个
forEach
。。。我似乎无法让它工作。编辑:Ohhh,数组本身上的函数。很好,好东西。我更喜欢
array.forEach()
方法。自动创建一个闭包,并摆脱所有难看的老式
for…loop
语法。谢谢我认为这里的混乱是,JS中的
closure==scope==function
大部分时间语义都不同,我想…哦,我认为这看起来更干净了。我过去遇到的唯一问题可能是,jQuery的
每个
都会迭代对象属性。有一次,我遇到了一个严重的错误,服务器返回了一些错误,jQuery冻结了页面,试图迭代一些不应该重复的内容。因为它,我现在可能有点偏执,哈哈。
var modules = [
    { name: 'ExchangeStatus', title: 'Exchange Status', column: 'left' },
    { name: 'Grid', title: 'Contacts', column: 'right' }
    { name: 'Filters', title: 'Filters', column: 'left' }
],
modulesUrl = '/Modules/';

$(modules).each( function(index, elem)
{
    var module = elem;

    // Get module HTML.
    $.ajax({
        url: modulesUrl + module.name,
        success: function (moduleHtml) {

            // Append module HTML to appropriate element.
            $('#' + module.column + 'Column').append(moduleHtml);

            // Custom event to trigger the module to load its data.
            var initializeModuleEvent = $.Event('initialize' + module.name);
            initializeModuleEvent.firstLoad = true;
            $(document).trigger(initializeModuleEvent);

        }
    });
}
}
);