可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm having a problem reformatting my JavaScript by removing a function that I have from within a loop.
Here is my JavaScript code:
$(document).ready(function () { //GET TWITCH TV STREAMERS' STATUS AND API CALL var twitchTvStreamers = ["FreeCodeCamp", "ESL_SC2", "OgamingSC2", "cretetion", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]; //OUT OF ALL THE TWITCH TV STREAMERS IN A TWITCH TV ARRAY FIND THOSE 8 STREAMERS LISTED for (var i = 0; i < twitchTvStreamers.length; i++) { //DO A GETJSON ON THIS ARRAY TO RETRIEVE INFORMATION FROM THE VALUES OF THOSE 8 TWITCH TV STREAMERS $.getjSON('https://wind-bow.glitch.me/twitch-api/streams' + val, function (st) { //var url="https://wind-bow.glitch.me/twitch-api/streams" channelName = val; //IF ANY OF THE STATUSES OF THE 8 TWITCH TV STREAMERS ARE EQUAL TO NULL, OR OFFLINE, THEN DO SOMETHING if (st.stream === null) { //GET JSON INFO OF THOSE OFFLINE STREAMERS $.getjSON('https://wind-bow.glitch.me/twitch-api/channels' + val, function (ch) { channelID = ch.Display_name; channelLogo = ch.logo; channelUrl = ch.url; streamContent = ch.content; //POST INFO TO DISPLAY AREA OF WEB APP (...ADD OTHER STUFF TO THIS APPEND LATER) $('#offline').append('<div class="TV-screen">'); }); } else //REPEAT SAME SCENARIO AS USED FOR OFFLINE STREAM STATUS $.getjSON('https://wind-bow.glitch.me/twitch-api/channels' + val, function (ch) { channelID = ch.Display_name; channelLogo = ch.logo; channelUrl = ch.url; streamContent = ch.content; $('#online').append('<div class="TV-screen">'); }); }
//with help from: https://www.youtube.com/watch?v=Nm2bXBlELZU&list=PLHdCowjFIBmJwYL9tPZOkn6CIVLg6Z36a, etc. etc......
I placed the above code into www.jshint.com and it gave the following results:
Three warnings":
- 11 Don't make functions within a loop.
- 42 Expected ')' and instead saw ''.
- 49 Unrecoverable syntax error. (100% scanned).
How can I reformat my code (at line 11) to include my get JSON function, but without it being within the loop?
回答1:
You've got a large number of errors in syntax, typos, wrong function names and wrong usage of the placeholders for deferred returns of the asynch calls. A summary of the errors is below. Meanwhile, run the code to make sure that it actually works.
$(document).ready(function(){ // Who we want to stalk today var twitchTvStreamers=["FreeCodeCamp", "ESL_SC2", "OgamingSC2", "cretetion", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]; // Get the status of each channel using the getChannelInfo() function for(channel of twitchTvStreamers){ getChannelInfo(channel); } }); // This function gets the status of each channel // and, depending whether it is online or offline, // calls the appendInfo() function with the online/offline parameter var getChannelInfo = channel => { $.getJSON('https://wind-bow.glitch.me/twitch-api/streams/' + channel) .done(function(info) { if (info.stream === null) appendInfo(channel,'offline'); else appendInfo(channel,'online'); }); } // This function gets info on whether the channel is online or offline. // Depending on this status, it gets the channel info // and appends it in the respective `<div>` var appendInfo = (channel,target) => { $.getJSON('https://wind-bow.glitch.me/twitch-api/channels/' + channel) .done( function(ch){ channelID = ch.display_name; channelLogo = ch.logo; channelUrl = ch.url; streamContent = ch.content; $('#'+target).append('<div class="TV-screen">'+channel+' is '+target); }); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="online"></div> <div id="offline"></div>
So, your problems with the code were:
channel = val;
sets the channel variable, not the val variable. val = channel
would set the val variable but that wouldn't work in your code either. You could set val like val = twitchTvStreamers[i];
getjSON
should be spelled as getJSON
- case matters!
ch.Display_name
won't work as the returned object key is spelled as display_name
. Again, be careful with your cases.
$('#offline').append('<div class="TV-screen">');
- this just adds a blank <div>
to the #offline
element. You would want to include some of the channel-specifit information here as well.
And, most important of all, you gotta understand exactly how JS Promise works. The last best resource I read on this was Kyle Simpson's Asynch & Performance book from his You don't know JS series. jQuery's getJSON
uses the Promise interface, so knowing the underlying technology definitely helps.
In a nutshell - when you are making an asynch call, the response takes a while to come through and meanwhile, other code executes. For example, you have a variable called status
, and you are making an API call for the statuses of Twitch channels foo and bar. Until the API response comes back, your code already prints out <div id="foo">
and <div id="bar">
on the page. Then the statuses come back, status of channel foo comes back as online and sets the status
variable as 'online'. Then, status of bar comes back as 'offline' and sets status
variable to offline. And, if not handled properly, JS returns this last value (offline), and it applies to all of your elements.
You have to be able to make the call and promise its result to the correct DOM element. I did it as following:
- Get the status
- If online, get the channel details, produce a DOM element, append to the 'online' div
- If offline, get the channel details, produce a DOM element, append to the 'offline' div
Here the sequence of producing and appending DOM elements does not cross the sequence of making AJAX calls and getting the results. It is the easiest to break this sequence down to separate functions and call them by each step, which I did.
回答2:
You forgot large number of brackets at the end. This is how your code might look like
$(document).ready(function() { //GET TWITCH TV STREAMERS' STATUS AND API CALL var twitchTvStreamers = ["FreeCodeCamp", "ESL_SC2", "OgamingSC2", "cretetion", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]; //OUT OF ALL THE TWITCH TV STREAMERS IN A TWITCH TV ARRAY FIND THOSE 8 STREAMERS LISTED twitchTvStreamers.map(function(val) { //DO A GETJSON ON THIS ARRAY TO RETRIEVE INFORMATION FROM THE VALUES OF THOSE 8 TWITCH TV STREAMERS $.getjSON('https://wind-bow.glitch.me/twitch-api/streams' + val, function(st) { //var url="https://wind-bow.glitch.me/twitch-api/streams" channelName = val; //IF ANY OF THE STATUSES OF THE 8 TWITCH TV STREAMERS ARE EQUAL TO NULL, OR OFFLINE, THEN DO SOMETHING if (st.stream === null) { //GET JSON INFO OF THOSE OFFLINE STREAMERS $.getjSON('https://wind-bow.glitch.me/twitch-api/channels' + val, function(ch) { channelID = ch.Display_name; channelLogo = ch.logo; channelUrl = ch.url; streamContent = ch.content; //POST INFO TO DISPLAY AREA OF WEB APP (...ADD OTHER STUFF TO THIS APPEND LATER) $('#offline').append('<div class="TV-screen">'); }); } else { //REPEAT SAME SCENARIO AS USED FOR OFFLINE STREAM STATUS $.getjSON('https://wind-bow.glitch.me/twitch-api/channels' + val, function(ch) { channelID = ch.Display_name; channelLogo = ch.logo; channelUrl = ch.url; streamContent = ch.content; $('#online').append('<div class="TV-screen">'); }); } }); // getJSON }); // map }); // ready
this fixes problems 2 and 3. But I'm stiil not sure what is val
in your code. I guess it's stream name, so I added it to:
- array.map() function instead of
for loop
to avoid 1st problem