Вызов jQuery Ajax в цикле с потерей ссылки на локальную переменную

#javascript #jquery #ajax

#javascript #jquery #ajax

Вопрос:

Я выполняю несколько вызовов jQuery ajax в цикле. Каждый раз, когда возвращается один из вызовов ajax, мне нужно ссылаться на значение, соответствующее исходному вызову ajax. Мой текущий код не работает должным образом, поскольку значение lskey переменной было изменено дальнейшими итерациями цикла.

Вот код:

 for (var i = 0, len = localStorage.length; i < len; i  ) {
        var lskey = localStorage.key(i);
        if (lskey.substr(0, 4) === 'form') {
            var postdata = localStorage.getItem(lskey); // Get the form data
            $.ajax({
                type: "POST",
                async: "false",
                url: "/Profile/PostForm",
                data: postdata,
                success: function (data) {
                    $('#rollinginfo').append('<br>'   data   ',key='   lskey);
                    localStorage.removeItem(lskey); // Remove the relevant localStorage entry
                }
            , error: function (data) { $('#rollinginfo').append('<br />ERR:'   data); }
            });


        }
    } 
  

Проблема в том, что lskey изменяется каждый раз при выполнении цикла, и поэтому при успешном обратном вызове нет ссылки на значение lskey, которое существовало во время вызова.

Как мне ссылаться на правильное значение lskey для каждого успешного обратного вызова?

Ответ №1:

 for (var i = 0, len = localStorage.length; i < len; i  ) {
    var lskey = localStorage.key(i);
    if (lskey.substr(0, 4) === 'form') {
        var postdata = localStorage.getItem(lskey); // Get the form data
        $.ajax({
            type: "POST",
            async: "false",
            url: "/Profile/PostForm",
            data: postdata,
            local_lskey: lskey
            success: function (data) {
                $('#rollinginfo').append('<br>'   data   ',key='   lskey);
                localStorage.removeItem(this.local_lskey); // Remove the relevant localStorage entry
            }
        , error: function (data) { $('#rollinginfo').append('<br />ERR:'   data); }
        });
    }
}
  

Это должно сработать.

Комментарии:

1. Я написал изворотливый странный поисковый запрос в Google и БАЦ! первый результат — это ваш ответ, большое спасибо! И ТАК далее!

Ответ №2:

В конце я добавил информацию о ключе к публикации на сервере, а затем вернул ее с сервера в формате JSON, чтобы функция успеха могла затем просто ссылаться на ключ, содержащийся в ответе сервера.

Ответ №3:

Рассматривали ли вы возможность объединения вызовов AJAX в цепочку? В принципе, вы можете выполнить один вызов AJAX, обработать результат, изменить lskey и т.д. Затем, когда вы будете готовы, увеличьте значение i и выполните второй вызов AJAX. Выполните цикл таким образом вместо использования for цикла…

Комментарии:

1. Спасибо. Думаю, я мог бы сделать это таким образом, но просто подумал, есть ли какой-нибудь способ «передать» значение функции success.

Ответ №4:

Вы могли бы поместить свой вызов ajax в его собственную функцию и передать в нее значения lskey и postData . Таким образом, localStorage.removeItem(lskey) переменная будет ссылаться на lskey в контексте функции, а не в контексте цикла.

Пример

Объявляем функцию —

 function postForm(postdata, lskey) {
  $.ajax({
    type: "POST",
    async: "false",
    url: "/Profile/PostForm",
    data: postdata,
    success: function(data) {
      $('#rollinginfo').append('<br>'   data   ',key='   lskey);
      localStorage.removeItem(lskey); // Remove the relevant localStorage entry
    },
    error: function(data) {
      $('#rollinginfo').append('<br />ERR:'   data);
    }
  });
}
  

Затем вы можете вызвать свою функцию из своего цикла —

 for (var i = 0, len = localStorage.length; i < len; i  ) {
  var lskey = localStorage.key(i);
  if (lskey.substr(0, 4) === 'form') {
    var postdata = localStorage.getItem(lskey); // Get the form data
    postForm(postdata, lskey);
  }
}
  

Вы также могли бы объявить функцию непосредственно перед циклом (присвоив ее переменной), а затем вызвать ее внутри цикла.

 var postForm = function(postdata, lskey) {
  $.ajax({
    type: "POST",
    async: "false",
    url: "/Profile/PostForm",
    data: postdata,
    success: function(data) {
      $('#rollinginfo').append('<br>'   data   ',key='   lskey);
      localStorage.removeItem(lskey); // Remove the relevant localStorage entry
    },
    error: function(data) {
      $('#rollinginfo').append('<br />ERR:'   data);
    }
  });
}
for (var i = 0, len = localStorage.length; i < len; i  ) {
  var lskey = localStorage.key(i);
  if (lskey.substr(0, 4) === 'form') {
    var postdata = localStorage.getItem(lskey); // Get the form data
    postForm(postdata, lskey);
  }
}
  

Комментарии:

1. @MattPowell Справедливый запрос — добавлены примеры.