javascript - getjson 函数成功后将 div 分割为 3 并附加到正文

标签 javascript jquery promise

这是对 twitch.tv 主播列表的一次尝试,属于 FreeCodeCamp 项目的一部分。 document.ready函数将数据追加到div(bs4卡片)后,需要按照3的顺序堆叠在card-decks中。 我正在尝试 splitByThree 函数,但它似乎不起作用。 如何使用 promise 来做到这一点?非常感谢任何帮助。

let streamers = ["ESL_SC2",
        "ESL_CSGO", "freecodecamp", "GeoffStorbeck", "terakilobyte", "habathcx", "notmichaelmcdonald", "RobotCaleb", "medrybw", "thomasballinger", "joe_at_underflow", "noobs2ninjas", "mdwasp", "beohoff", "xenocomagain"
    ];
    
    let getDATA = function(arr) {
        let cb = '?client_id=c292fn290f4pac7cpk4j4t137uk3tn&callback=?';
        let url = 'https://api.twitch.tv/kraken/';

        arr.forEach(function(stream) {

            let newUrl = url + 'streams/' + stream + cb;


            $.getJSON(newUrl).success(function(data) {
                let obj = {};
                let streaming = (data.stream === null) ? false : true;
                if (streaming) {
                    obj.theme = 'card-success';
                    obj.username = stream;
                } else {
                    obj.theme = 'card-danger';
                    obj.username = stream;
                }
                
                $.getJSON(url + 'users/' + stream + cb).done(function(data, textStatus, jqXHR) {
                    obj.logo = data.logo;
                    $(".streamers").append('<div class="streamer card col-4 ' + obj.theme + '"><img class="rounded w-25" src=' + obj.logo + '>' + obj.username + '</div>');
                });
            });            
        });
    };

    function splitByThree() {
        var divs = $(".streamers > .streamer");
        for (var i = 0; i < divs.length; i += 3) {
            divs.slice(i, i + 3).wrapAll("<div class='card-deck'></div>");
        }
    }

    let readyFN  = function () {
        getDATA(streamers).then(function(){return splitByThree()});
        
    };
    $(document).ready(readyFN);
    
<link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="streamers"></div>

最佳答案

为了执行:

getDATA(streamers).then(function(){return splitByThree()});

函数 getDATA 必须返回一个数组 deferred 对象。 When 这个数组有 done 你可以执行splitByThree函数。

如果您想使用deferred then为了处理完成和失败,您可以拒绝,而不是在发生失败时解决延迟元素。

这样你的代码行就变成了:

$.when.apply($, getDATA(streamers)).done(function () {
    splitByThree()
});

代码片段:

let streamers = ["ESL_SC2",
                 "ESL_CSGO", "freecodecamp", "GeoffStorbeck", "terakilobyte", "habathcx", "notmichaelmcdonald", "RobotCaleb", "medrybw",
                 "thomasballinger", "joe_at_underflow", "noobs2ninjas", "mdwasp", "beohoff", "xenocomagain"
                ];


let getDATA = function (arr) {
  //
  // create and initialize the deferred array to return
  //
  var deferredArr = [];
  arr.forEach(function (ele, idx) {
    deferredArr.push($.Deferred());
  });


  let cb = '?client_id=c292fn290f4pac7cpk4j4t137uk3tn&callback=?';
  let url = 'https://api.twitch.tv/kraken/';

  arr.forEach(function (stream, idx) {
    let newUrl = url + 'streams/' + stream + cb;
    $.getJSON(newUrl).success(function (data) {
      let obj = {};
      let streaming = (data.stream === null) ? false : true;
      if (streaming) {
        obj.theme = 'card-success';
        obj.username = stream;
      } else {
        obj.theme = 'card-danger';
        obj.username = stream;
      }

      $.getJSON(url + 'users/' + stream + cb).done(function (data, textStatus, jqXHR) {
        obj.logo = data.logo;
        $(".streamers").append('<div class="streamer card col-4 ' + obj.theme + '"><img class="rounded w-25" src=' + obj.logo + '>' + obj.username + '</div>');
        //
        // resolve the current deferred element
        //
        deferredArr[idx].resolve();
      }).fail(function () {
        //
        // resolve (reject using then instead of done)
        // the current deferred element
        //
        deferredArr[idx].resolve();
      });
    }).fail(function () {
      //
      // resolve (reject using then instead of done)
      // the current deferred element
      //
      deferredArr[idx].resolve();
    });
  });
  return deferredArr;
};

function splitByThree() {
  console.log('splitByThree runs....');
  var divs = $(".streamers > .streamer");
  for (var i = 0; i < divs.length; i += 3) {
    divs.slice(i, i + 3).wrapAll("<div class='card-deck'></div>");
  }
}

let readyFN = function () {
  $.when.apply($, getDATA(streamers)).done(function () {
    splitByThree()
  });
};
$(document).ready(readyFN);
<link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="streamers"></div>

关于javascript - getjson 函数成功后将 div 分割为 3 并附加到正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42234111/

相关文章:

javascript - 如何在 Node 模块中访问具有相对路径的文件?

javascript - 当其中一个条件是 promise 而另一个不是时,是否有惯用的方式在 JavaScript 中表达 "if (c1 || c2)"?

javascript - 如何使用 Node.js 进行异步 api 调用?

javascript - 使用复选框显示/隐藏元素

jquery - 在jquery中为canvas元素添加id值

javascript - HTML 大小调整问题

javascript - 在内部 promise 解决之前 promise 解决

javascript - 为什么我从 repl.it 上的这段代码中看到 "Promise { <pending> }"?

javascript - 是否有 'fixed header' 或 'sticky header' 用于 native react ?

javascript - 第二次点击时文本卡住