JQuery嵌套了$ .when ... then语句

时间:2016-05-24 17:49:27

标签: javascript jquery

我正在尝试进行FreeCodeCamp练习,我称之为Twitch TV API。对于每个频道,我调用API来获取频道数据。然后,我随后调用以获取流数据。对通道信息的调用包含在$ .when ... then循环中,似乎工作正常。然后我添加了第二个调用以获取流数据,代码似乎不等待该调用完成。



$(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>
&#13;
&#13;
&#13;

JSBin链接显示代码。第51行显示第二个ajax调用。

代码应该填充一个数组,然后在完成所有调用后显示数据。我很欣赏,等待所有这些调用完成的生产系统将导致用户体验不足。

1 个答案:

答案 0 :(得分:0)

您需要稍微重新编写它,以便从getChannelData返回的承诺正在等待在forEach中创建的承诺。

  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
    });
  }

然后你会像以下一样使用它:

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