如何在数组循环中 运行 ajax 请求
How to run ajax request in array loop
好的,所以我正在创建一个网络应用程序,我 运行 遇到了一些问题
首先,我向 api 端点发出请求,此 returns 一个 json 响应,我获取我需要的内容并将其添加到键值数组中
然后我必须遍历这个数组中的所有项目,对于每个项目我需要向第二个 api 端点发出请求,returns 一些 html
然后我需要将此 html 附加到页面上的元素中
我需要一个接一个地完成这个,我遇到的问题是 .each() 循环立即完成,而请求仍在后台进行,这意味着食物被附加到 html在他们应该
之后页面上的元素
如何让循环等到请求完成并附加 html,然后再移动到数组中的下一个项目
$("#middlebox").fadeTo(3000, 0, function() {
$("#middlebox").html(LOADING);
});
$("#middlebox").fadeTo(3000, 1, function() {
var API_URL = window.location.href + 'api.php?action=channels&category='+$this.data("text")+'&username='+$("#username").val()+'&password='+$("#password").val();
var CHANNELS = {};
var API_CHANNELS = '<div class="Live">';
$.getJSON(API_URL).done( function( API_RESULT ) {
$.each( API_RESULT.items, function( API_INDEX, API_ITEM ) {
var API_ID = API_ITEM.stream_id;
var API_ICON = API_ITEM.stream_icon;
CHANNELS[API_ID] = API_ICON;
});
}).then( function() {
$.each( CHANNELS, function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
$.ajax({
url:EPG_URL,
type: 'GET',
dataType: 'html',
success:function(content,code) {
API_CHANNELS += content;
}
});
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
API_CHANNELS += '</div>';
$("#middlebox").html(API_CHANNELS);
$("#middlebox").fadeTo(3000, 1, function() {
});
});
});
});
Ajax 调用是异步的,因此您不能使用同步循环来处理请求。
您可以使用 Promise.all
等待所有 ajax 请求,然后循环处理回复。
Promise.all(CHANNELS.map(function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
return $.ajax({
URL: EPG_URL,
type: 'GET',
dataType: 'html'
}).then(function(content) {
return [CHANNEL_KEY, CHANNEL_VALUE, content];
});
})).then(function(channels) {
$.each(channels, function(CHANNEL_KEY, CHANNEL_VALUE, content) {
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
API_CHANNELS += content;
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
/* ... */
});
});
好的,所以我正在创建一个网络应用程序,我 运行 遇到了一些问题
首先,我向 api 端点发出请求,此 returns 一个 json 响应,我获取我需要的内容并将其添加到键值数组中
然后我必须遍历这个数组中的所有项目,对于每个项目我需要向第二个 api 端点发出请求,returns 一些 html
然后我需要将此 html 附加到页面上的元素中
我需要一个接一个地完成这个,我遇到的问题是 .each() 循环立即完成,而请求仍在后台进行,这意味着食物被附加到 html在他们应该
之后页面上的元素如何让循环等到请求完成并附加 html,然后再移动到数组中的下一个项目
$("#middlebox").fadeTo(3000, 0, function() {
$("#middlebox").html(LOADING);
});
$("#middlebox").fadeTo(3000, 1, function() {
var API_URL = window.location.href + 'api.php?action=channels&category='+$this.data("text")+'&username='+$("#username").val()+'&password='+$("#password").val();
var CHANNELS = {};
var API_CHANNELS = '<div class="Live">';
$.getJSON(API_URL).done( function( API_RESULT ) {
$.each( API_RESULT.items, function( API_INDEX, API_ITEM ) {
var API_ID = API_ITEM.stream_id;
var API_ICON = API_ITEM.stream_icon;
CHANNELS[API_ID] = API_ICON;
});
}).then( function() {
$.each( CHANNELS, function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
$.ajax({
url:EPG_URL,
type: 'GET',
dataType: 'html',
success:function(content,code) {
API_CHANNELS += content;
}
});
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
API_CHANNELS += '</div>';
$("#middlebox").html(API_CHANNELS);
$("#middlebox").fadeTo(3000, 1, function() {
});
});
});
});
Ajax 调用是异步的,因此您不能使用同步循环来处理请求。
您可以使用 Promise.all
等待所有 ajax 请求,然后循环处理回复。
Promise.all(CHANNELS.map(function( CHANNEL_KEY, CHANNEL_VALUE ) {
var EPG_URL = window.location.href + 'api.php?action=epg&id='+CHANNEL_KEY+'&username='+$("#username").val()+'&password='+$("#password").val();
return $.ajax({
URL: EPG_URL,
type: 'GET',
dataType: 'html'
}).then(function(content) {
return [CHANNEL_KEY, CHANNEL_VALUE, content];
});
})).then(function(channels) {
$.each(channels, function(CHANNEL_KEY, CHANNEL_VALUE, content) {
API_CHANNELS += '<div class="channel focusable"><div class="LiveIcon"><img src="' + CHANNEL_VALUE + '" class="TvIcon"></div>';
API_CHANNELS += content;
API_CHANNELS += '</div>';
});
$("#middlebox").fadeTo(3000, 0, function() {
/* ... */
});
});