如何在每个循环中完成单独的 ajax 调用后 运行 编码
How to run code after separate ajax calls have completed within an each loop
我的HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<ul id="output">
<template id="list-template">
<a href="{{url}}" target="_blank">
<li>
<p><strong>{{name}}</strong></p>
<p><img src="{{logo}}" alt="{{name}} logo"></p>
</li>
</a>
</template>
</ul>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script>
</body>
</html>
我的JS代码:
$( document ).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var allStreams = [];
var arr = [];
$.each(channels, function(i, channelName){
var xhr = $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp',
success: function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
allStreams[i] = {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
$.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp',
success: function(channelData) {
allStreams[i] = {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
} // close inner success
}); // close inner $.ajax()
} // close else
} // close outer success
}); // close outer $.ajax()
arr.push(xhr);
}); // close $.each()
console.log(allStreams);
$.when.apply($, arr).then(function(){
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
})
/* deleted accounts
- brunofin
- comster404
*/
}); // close .ready()
在外部和内部 ajax 请求完成所有迭代后,我需要以下代码 运行:
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
您可能会注意到,我已尝试实施此处的建议:Is it possible to run code after all ajax call completed under the for loop statement?
...但这似乎只有在 $.each() 循环中只有一个 ajax 调用时才有效。
我如何让它与我的 $.each() 循环中的两个单独的 ajax 请求一起工作,每个请求都有多次迭代?目前只有外部 ajax 迭代传送的实时流显示在我的列表中。
利用 $.ajax returns 对您有利的承诺。
在 .then 回调中,返回一个值解析 .then 返回的承诺 - 然而,返回一个 Promise 将意味着 .then 将等待返回的 Promise 并解析为该值
这也意味着,通过使用 Array#map,无需推送到数组或数组[i] = 任何类型的代码 - 它全部由 .map 和承诺的解析值处理
$(document).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var arr = channels.map(function(channelName) {
return $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp'
}).then(function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
return {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
return $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp'
}).then(function(channelData) {
return {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
});
}
});
});
$.when.apply($, arr).then(function() {
var allStreams = [].slice.call(arguments);
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
});
});
我正在考虑使用基于 promise 的解决方案,但您的方案似乎可以通过添加 2 个 if 子句来解决(如果使用 promise 可以减少到 1 个)。我已将您的呈现逻辑放入一个函数中,并在所有 ajax 请求完成时调用它,就是这样。
$( document ).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var allStreams = [];
var arr = [];
$.each(channels, function(i, channelName){
var xhr = $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp',
success: function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
allStreams[i] = {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
if(channels.length === allStreams.length){
allStreamsFetched();
}
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
$.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp',
success: function(channelData) {
allStreams[i] = {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
if(channels.length === allStreams.length){
allStreamsFetched();
}
} // close inner success
}); // close inner $.ajax()
} // close else
} // close outer success
}); // close outer $.ajax()
arr.push(xhr);
}); // close $.each()
function allStreamsFetched(){
console.log(allStreams);
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
}
});
我的HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<ul id="output">
<template id="list-template">
<a href="{{url}}" target="_blank">
<li>
<p><strong>{{name}}</strong></p>
<p><img src="{{logo}}" alt="{{name}} logo"></p>
</li>
</a>
</template>
</ul>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script>
</body>
</html>
我的JS代码:
$( document ).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var allStreams = [];
var arr = [];
$.each(channels, function(i, channelName){
var xhr = $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp',
success: function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
allStreams[i] = {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
$.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp',
success: function(channelData) {
allStreams[i] = {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
} // close inner success
}); // close inner $.ajax()
} // close else
} // close outer success
}); // close outer $.ajax()
arr.push(xhr);
}); // close $.each()
console.log(allStreams);
$.when.apply($, arr).then(function(){
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
})
/* deleted accounts
- brunofin
- comster404
*/
}); // close .ready()
在外部和内部 ajax 请求完成所有迭代后,我需要以下代码 运行:
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
您可能会注意到,我已尝试实施此处的建议:Is it possible to run code after all ajax call completed under the for loop statement?
...但这似乎只有在 $.each() 循环中只有一个 ajax 调用时才有效。
我如何让它与我的 $.each() 循环中的两个单独的 ajax 请求一起工作,每个请求都有多次迭代?目前只有外部 ajax 迭代传送的实时流显示在我的列表中。
利用 $.ajax returns 对您有利的承诺。
在 .then 回调中,返回一个值解析 .then 返回的承诺 - 然而,返回一个 Promise 将意味着 .then 将等待返回的 Promise 并解析为该值
这也意味着,通过使用 Array#map,无需推送到数组或数组[i] = 任何类型的代码 - 它全部由 .map 和承诺的解析值处理
$(document).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var arr = channels.map(function(channelName) {
return $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp'
}).then(function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
return {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
return $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp'
}).then(function(channelData) {
return {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
});
}
});
});
$.when.apply($, arr).then(function() {
var allStreams = [].slice.call(arguments);
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
});
});
我正在考虑使用基于 promise 的解决方案,但您的方案似乎可以通过添加 2 个 if 子句来解决(如果使用 promise 可以减少到 1 个)。我已将您的呈现逻辑放入一个函数中,并在所有 ajax 请求完成时调用它,就是这样。
$( document ).ready(function() {
var $ul = $('#output');
var listTemplate = $('#list-template').html();
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var allStreams = [];
var arr = [];
$.each(channels, function(i, channelName){
var xhr = $.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/streams/' + channelName,
dataType: 'jsonp',
success: function(data) {
if (data.stream) { // i.e. if it's not null and currently streaming
allStreams[i] = {
name: data.stream.channel.display_name,
url: data.stream.channel.url,
logo: data.stream.channel.logo,
status: data.stream
};
if(channels.length === allStreams.length){
allStreamsFetched();
}
} else { // i.e. it's not currently streaming, do a separate request to get the channel info.
$.ajax({
url: 'https://wind-bow.gomix.me/twitch-api/channels/' + channelName,
dataType: 'jsonp',
success: function(channelData) {
allStreams[i] = {
name: channelData.display_name,
url: channelData.url,
logo: channelData.logo
};
if(channels.length === allStreams.length){
allStreamsFetched();
}
} // close inner success
}); // close inner $.ajax()
} // close else
} // close outer success
}); // close outer $.ajax()
arr.push(xhr);
}); // close $.each()
function allStreamsFetched(){
console.log(allStreams);
$.each(allStreams, function(i, stream) {
$ul.append(Mustache.render(listTemplate, stream));
});
}
});