我目前正在阅读How do I return the response from an asynchronous call?,这似乎与我下面的代码无法正常工作的原因有关。 getJSON for循环之后的我的console.log在循环之前执行,因此返回null。 getJSON循环中的console.log返回推入数组的对象。
在多次阅读引用的答案之后,我对如何在回调或承诺中实现解决方案感到困惑。在下面的代码中我需要做什么才能使用回调或promise,以便外部console.log返回数据?
function channel() {
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var channelData = [];
for(var x = 0; x < channels.length; x++) {
$.getJSON(`https://api.twitch.tv/kraken/channels/${channels[x]}?callback=?`, function(data) {
console.log(data.display_name);
// console.log(data);
channelData.push( { display_name:data.display_name, logo:data.logo, url:data.url, game:data.game, status:data.status } );
console.log(channelData);
});
}
console.log(channelData);
}
答案 0 :(得分:3)
$.getJSON
方法返回一个Promise,所以你可以等待所有这些完成。将所有$.getJSON
次调用推送到数组中,然后将数组传递给$.when
:
function channel() {
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var channelData = [];
var gets = [];
var success = function(data) {
channelData.push({
display_name: data.display_name,
logo: data.logo,
url: data.url,
game: data.game,
status: data.status
})
};
for (var x = 0; x < channels.length; x++) {
gets.push(
$.getJSON(`https://api.twitch.tv/kraken/channels/${channels[x]}?callback=?`)
);
}
$.when.apply(null, gets).done(function() {
var results = arguments;
for (var i = 0, z = results.length; i < z; i++) {
var data = results[i][0];
success(data);
}
console.log(channelData);
});
}
channel()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
这里的技巧是$.getJSON
返回的内容类似于Promise(它实际上是一个jQuery Deferred对象。另外,在$.when
结算之前不会调用成功回调。
因此,您需要将参数解析为传递给$.when
的{{1}}函数的函数。
不幸的是,这不像done
的典型调用那样有效。相反,它实际上是一个带有数字键的对象。这些键的值是通常传递给Promise.all
回调的参数数组:即数据,结果文本(“成功”)和jqXHR对象。
因此,我们遍历每个属性并获取第一个值,然后将其传递给解析数据的函数。 Phew:)。
答案 1 :(得分:1)
$ .getJSON是一个异步函数,所以代码在继续之前不会等待它的响应。也就是说,代码将通过 for循环 发出多个异步调用,然后立即调用外部console.log。
要正确执行外部“console.log”,您必须向通道功能添加一个回调函数,并且只要异步调用有响应,就会调用它。
示例:
function channel(callback) {
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var channelData = [];
for(var x = 0; x < channels.length; x++) {
$.getJSON(`https://api.twitch.tv/kraken/channels/${channels[x]}?callback=?`, function(data) {
console.log(data.display_name);;
channelData.push( { display_name:data.display_name, logo:data.logo, url:data.url, game:data.game, status:data.status } );
return callback(channelData);
});
}
}
channel(function(response) {
console.log(response); // Where response is your channel Data
/* do something with the return channel data */
// Note this function will be called multiple times
})
答案 2 :(得分:1)
function getData(channel){
return new Promise(function(resolve,reject){
try{
$.getJSON(`https://api.twitch.tv/kraken/channels/${channel}?callback=?`, function(data) {
resolve(data);
})
}catch(ex){
reject(ex);
}
})
}
function channel() {
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var promises=[];
for(var x = 0; x < channels.length; x++) {
promises.push(getData(channels[x]));
}
Promise.all(promises).then(datas){
var channelData = [];
for(var data in datas){
channelData.push( { display_name:data.display_name, logo:data.logo, url:data.url, game:data.game, status:data.status } );
}
console.log(channelData);
}
}
答案 3 :(得分:1)
passing an array of deferreds到$.when
:
var channels = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
$.when.apply($, channels.map(x => $.getJSON(`https://api.twitch.tv/kraken/channels/${x}?callback=?`)))
.then(function(){
// here you'll have all the responses
console.log(arguments)
})