[英]Array Scope Within Javascript Function is Null Outside of Inner AJAX Loop
我目前正在閱讀如何從異步調用返回響應? 這似乎與為什么我下面的代碼無法按預期運行有關。 getJSON for循環之后的console.log在循環之前執行,因此返回null。 getJSON循環中的console.log返回被推入數組的對象。
多次閱讀引用的答案后,我對如何在回調或Promise中實現解決方案感到更加困惑。 我需要在下面的代碼中使用回調或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);
}
$.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
返回的內容$.getJSON
Promise(它實際上是jQuery Deferred對象。此外,在$.when
解析之前,不會調用成功回調。
所以,你需要分析的參數傳遞給那么函數$.when
的done
功能。
不幸的是,這並不像對Promise.all
的典型調用那樣工作。 相反,它實際上是一個帶有數字鍵的對象。 這些鍵的值是參數的數組,通常會傳遞給success
回調:即數據,結果文本(“成功”)和jqXHR對象。
因此,我們遍歷每個屬性並獲取第一個值,然后將其傳遞給解析數據的函數。 ew :)。
$ .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
})
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);
}
}
通過傳遞一系列遞延給$.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)
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.