Как отправить одно и то же сообщение на несколько серверов и связать данные с отдельным сообщением

#javascript #jquery #ajax #post

#javascript #jquery #ajax #Публикация

Вопрос:

Я пытаюсь отправить запрос post на несколько серверов (возможно, в CORS). Для этого у меня есть массив с сообщениями jQuery и зарегистрировать ту же функцию обратного вызова для отдельных сообщений, что и так:

 var requestUrls = getRequestUrlArrayFromForm();
var companyNames = getCompanyNamesArrayFromForm();

cleanTable();
for(var i = 0; i < requestUrls.length; i  ) {

  postings.push($.post(requestUrls[i],
    someXmlString                               
  ));

  postings[i].done(function( response , textStatus, jqXHR) {    

    console.log(i); // the number printed here is always the same even for requestUrls.length > 1
    addToTable(companyNames[i], response);      

  }).fail(function( jqXHR ) {
    // do something
  });

}
  

Моя проблема сейчас в том, что я хочу запомнить некоторые данные, связанные с каждым отдельным сообщением, как в этом примере с названием компании. Но в функции успеха post я не знаю, какой из этих запросов n-post я и поэтому не могу узнать правильный индекс, чтобы получить доступ к правильному значению в моем массиве CompanyName. И хорошо, я думаю, это из-за асинхронного поведения ajax. Но в любом случае эта проблема должна быть как-то разрешима.

Итак, возможно ли передать некоторые данные в объект post, который не отправляется на сервер, а просто запоминается клиентом и доступен в выполненной функции-обратном вызове?

Заранее спасибо.

Ответ №1:

Вам нужно сделать что-то вроде этого

 var requestUrls = getRequestUrlArrayFromForm();
var companyNames = getCompanyNamesArrayFromForm();

cleanTable();
var postings = [];
for (var i = 0; i < requestUrls.length; i  ) {
    postings.push($.post(requestUrls[i], someXmlString));
}

$.when.apply($, postings).done(function () {
    for (var i in arguments) {
        addToTable(companyNames[i], arguments[i][0]); // the response
    }
});
  

Согласно комментариям OP, обновленный ответ

 var requestUrls = getRequestUrlArrayFromForm();
var companyNames = getCompanyNamesArrayFromForm();

cleanTable();
for (var i = 0; i < requestUrls.length; i  ) {
    (function (i) {
        $.post(requestUrls[i], someXmlString).done(function (resp) {
            addToTable(companyNames[i], resp);
        });
    })(i);
}
  

вам нужно обернуть его с помощью closure.

пример рабочей демонстрации

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

1. итак, почему вы используете функцию apply вместе с when?

2. @tobi хороший вопрос, $.When может принимать любое количество аргументов, обычно отложенных объектов . apply используется здесь для удобной передачи параметров в виде массива и для передачи контекста. $.when.apply($, postings).done() буквально означает, когда все эти обещания будут выполнены… сделайте что-нибудь .

3. итак, если я правильно понял это с when , я могу что-то сделать, если на все сообщения будут даны ответы.. я пытаюсь заполнять таблицу шаг за шагом по мере поступления каждого ответа post :/

Ответ №2:

Как насчет чего-то подобного?

 var requestUrls = getRequestUrlArrayFromForm();
var companyNames = getCompanyNamesArrayFromForm();

cleanTable();
for(var i = 0; i < requestUrls.length; i  ) {

  $.post( requestUrls[i], someXmlString)
    .done(function(response , textStatus, jqXHR) {
        addToTable(companyNames[i], response);
    })
    .fail(function( jqXHR ) {
        // do something
    });

}
  

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

1. код в done по-прежнему выполняется только после завершения цикла for, и я получаю значение requestUrls.length, как в моем примере

Ответ №3:

Возможно, функция-оболочка поможет:

 var requestUrls = getRequestUrlArrayFromForm();
var companyNames = getCompanyNamesArrayFromForm();

cleanTable();
for(var i = 0; i < requestUrls.length; i  ) {

    postings.push($.post(requestUrls[i],
        someXmlString                               
    ));

    postings[i].done((function(j){ 
        return function( response , textStatus, jqXHR ) {    
            console.log(j); 
            addToTable(companyNames[j], response);      
        }
    })(i)).fail(function( jqXHR ) {
        // do something
    });

}
  

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

1. нет, эта функция не вызывается ответом jquerys post