2016-05-24 9 views
0

Ich versuche eine FreeCodeCamp-Übung zu machen, wo ich die Twitch TV API anrufe. Für jeden Kanal rufe ich die API an, um die Kanaldaten zu erhalten. Ich mache dann einen nachfolgenden Anruf, um die Streaming-Daten zu erhalten. Der Aufruf für die Kanalinformationen wird in eine $ .when ... then-Schleife eingeschlossen und scheint gut zu funktionieren. Ich fügte dann einen zweiten Anruf hinzu, um die Stream-Daten zu erhalten, und der Code scheint nicht darauf zu warten, dass dieser Anruf beendet wird.

$(document).ready(function() { 
 

 
    'use strict'; 
 

 
    var dataArray = []; // This holds all the channels that I find. I then sort to get the most popular first. 
 

 
    $.when(
 
    // TODO this should be some sort of loop to make it more flexible 
 
    getChannelData("https://api.twitch.tv/kraken/search/channels?api_version=3&q=all&limit=10&offset=0&callback=?") // First 10 
 
).then(function() { 
 
    sortData(); 
 
    displayData(); 
 
    }); 
 

 
    function getChannelData(channelStatement) { 
 

 
    return $.getJSON(channelStatement, function(channelData) { 
 

 
     channelData.channels.forEach(function(element) { 
 

 
     // Get stream details 
 
     var channel; 
 

 
     channel = { 
 
      logo: (element.logo === null) ? "https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png" : element.logo, // Channel: Url for image 
 
      displayName: element.display_name, // Channel: Broadcaster name 
 
      channelName: element.name, // Channel: Channel name 
 
      url: element.url, // Channel: Used to generate link to twitch page 
 
      game: element.game, // Channel: As the name suggests 
 
      status: element.status, // Chaneel: Description of the stream 
 
      views: element.views, // Channel: As the name suggests 
 
      onLine: true 
 
     }; 
 

 
     //dataArray.push(channel); 
 

 
     var streamUrl = "https://api.twitch.tv/kraken/streams/" + element.name + "?api_version=3&callback=?"; 
 

 
     $.when(
 
      getStreamData(streamUrl, channel) 
 
     ) 
 
      .then(function() { 
 
      dataArray.push(channel); 
 
      }); 
 
     }); // channel data forEach 
 
    }); 
 
    } 
 

 

 
    function getStreamData(streamUrl, channel) { 
 
    return $.getJSON(streamUrl, function(stream) { 
 
     channel.onLine = (stream.stream === null) ? false : true; 
 
    }); 
 
    } 
 

 

 
    function sortData() { 
 

 
    } 
 

 
    function displayData() { 
 

 
    } 
 
}); // end ready
<!DOCTYPE html> 
 

 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="utf-8" /> 
 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> 
 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" 
 
     crossorigin="anonymous"> 
 
    <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'> 
 
    <link rel="stylesheet" type="text/css" href="style.css"> 
 

 
    <title>Twitch TV</title> 
 
</head> 
 

 
<body> 
 
    <div class="container-fluid"> 
 
     <ol id="twitchList"> 
 
     </ol> 
 
    </div> 
 

 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> 
 
    <script src="TwitchTV.js"></script> 
 
</body> 
 

 
</html>

Dieser JSBin Link zeigt den Code. Zeile 51 zeigt den zweiten Ajax-Ruf.

Der Code sollte ein Array auffüllen und dann nach Abschluss aller Anrufe die Daten anzeigen. Ich schätze es, dass ein Produktionssystem, das darauf wartet, dass alle diese Anrufe abgeschlossen werden, zu einer weniger als genialen Benutzererfahrung führt.

+0

Der Code sollte in Ihrer Frage einbezogen werden. JSBin Link ist nicht erforderlich, aber es könnte nicht schaden, in der Frage zu sein, jedoch ist der Code in der Frage erforderlich. –

+0

Aktualisiert mit Code wie empfohlen. –

+1

Es ist sicherlich möglich zu tun, was Sie fragen, aber es ist eine ziemlich verschwenderische Verwendung von HTTP-Anfragen. Gibt es eine Möglichkeit, dass Sie Ihre Stream-Daten nur dann anzeigen lassen können, wenn der Benutzer bestimmte Informationen anzeigt und nicht sofort? Sie können sich vorstellen, wenn Sie 20 oder mehr Kanäle zurückgegeben haben, müssten Sie dann weitere 20 HTTP-Anfragen stellen (und warten, bis sie beendet sind), bevor Sie ** irgendetwas anzeigen könnten. – Adam

Antwort

0

Sie müssen es leicht neu organisieren, so dass das Versprechen, das Sie von getChannelData zurückgeben, auf den Versprechen wartet, die in Ihrem forEach erstellt werden.

function getChannelData(channelStatement) { 

    return $.getJSON(channelStatement).then(function(channelData) { 

     return $.when.apply(null, channelData.channels.map(function(element) { 

     // Get stream details 
     var channel = { 
      logo: (element.logo === null) ? "https://upload.wikimedia.org/wikipedia/commons/3/33/White_square_with_question_mark.png" : element.logo, // Channel: Url for image 
      displayName: element.display_name, // Channel: Broadcaster name 
      channelName: element.name, // Channel: Channel name 
      url: element.url, // Channel: Used to generate link to twitch page 
      game: element.game, // Channel: As the name suggests 
      status: element.status, // Chaneel: Description of the stream 
      views: element.views, // Channel: As the name suggests 
      onLine: true 
     }; 

     //dataArray.push(channel); 

     var streamUrl = "https://api.twitch.tv/kraken/streams/" + element.name + "?api_version=3&callback=?"; 

     return getStreamData(streamUrl, channel); 
     }); // channel data map 
    }); 
    } 

würden Sie dann gerne verwenden:

getChannelData(whatever).then(function() { 
    console.log(arguments); // this is dataArray 
}); 
+0

Ich habe einen Leckerbissen verwendet. Die einzige Änderung, die ich an Ihrem Code vorgenommen habe, war, die auskommentierte Zeile, die das Array auffüllt, wieder hinzuzufügen. Ich werde jetzt den Code für die nächste Stunde anstarren, um sicherzustellen, dass ich es verstehe! Danke für Ihre Hilfe. –