2015-09-06 3 views
0

Я новичок в Jquery и имеют некоторый код, который перебирает массив и загружает HTML из АЯКС запроса на каждой итерации цикла:Jquery асинхронные вызовы в порядке

$.each(arr, function (data) { 
    $.get('/Quote/LoadQuoteItemCost', { 'i': i }, function (html) { 
     $('#myTable).append(html); 
     // There are a few more lines which modify the html which I've left out 
    }); 
    i++; 
}); 

Моя проблема заключается в том, что ответы присоединяются к #myTable в случайном порядке, я предполагаю из-за асинхронного характера JQuery. Как я могу обеспечить, чтобы мои ответы были добавлены в мою таблицу в порядке их повторения через массив?

Я попытался асинхронным = ложь, но она амортизируется в моем браузере (и видела много постов, говоря не использовать)

+1

отправить обратно идентификатор и собирать ответы, пока все предыдущие Иды получены. если да: добавьте. если нет: дождитесь следующего ответа –

+0

или используйте jquery-эквивалент 'Promise.all' - так, как только все' $ .get' запустится, вы можете просмотреть результаты в порядке ** ** ** - при условии, что jqueery even имеет эквивалент 'Promise.all' –

ответ

1

Вот как бы я сделать это с помощью родного (в некоторых браузерах) Promise

Promise.all(arr.map(function(data, i) { 
    return $.get('/Quote/LoadQuoteItemCost', { 'i': i }); 
})).then(function(results) { 
    results.forEach(function (html, n) { 
     var data = arr[n]; 
     $('#myTable').append(html); 
     ... 
    }); 
}); 

эквивалент JQuery, кажется, $.when, однако, она принимает несколько (обещание) аргументы (а не массив Promises) , а затем функция получает несколько «результатов», а не один массив результатов - поэтому вся процедура будет немного отличаться от «(почти) чистого JS» выше, но это должно вас заставить

Редактировать : Я чувствую себя грязным, но я уверен, что это сделает то, что вы хотите, используя больше jQuery, чем мне удобно: p

$.when.apply(null, $.map(arr, function(data, i) { 
    return $.get('/Quote/LoadQuoteItemCost', { 'i': i }); 
})).then(function() { 
    $.each(arguments, function (n, html) { 
     var data = arr[n]; 
     $('#myTable').append(html); 
     ... 
    }); 
}); 
+0

Решение JQuery работает очень хорошо, но браузер печатает «успех» на странице - где я могу это остановить? –

+0

ясно, что «успех» является частью html, возвращающегося из $ .get console.log параметра html, чтобы увидеть, что это такое –

+0

Странно, html - это массив с [0], являющийся html, [1] успех "и [2] просто быть пустым объектом. –

0

Вы должны сделать другие вызовы на $ .get в успехе предшествующего $ .get в обратный вызов рекурсивно & поддерживать счетчик/переменную, чтобы остановить рекурсию, когда весь массив «arr» потребляется. Таким образом, следующий $ .get будет инициирован только после возвращения предыдущего ответа $ .get.

+1

, это стоит много времени. не является хорошим решением. улавливать результаты - лучший способ сделать это. Я не буду голосовать за ваш ответ, потому что это регулярное решение, но я бы не рекомендовал его. –

+0

Да, вы правы, это как-то в основном имитирует поведение синхронного вызова. – zeppelin

1

Концепция Я объяснил в комментариях теперь скрипкой и код:

var responses = [], 
    highestNumber = -1, 
    highestReceivedNumber = -1; 
function handleResponse(id, data) { 
    highestReceivedNumber = Math.max(highestReceivedNumber, id); 
    responses[id] = data; 
    if(id===highestNumber+1) 
     for(i=id;i<=highestReceivedNumber;i++) 
      if(!responses[i]) return; 
      else $('div:eq(0)').append(responses[i]) && highestNumber++; 
} 

взгляните на эту скрипку: http://jsfiddle.net/4udeg6wz/

Смежные вопросы