2017-02-14 10 views
0

Это попытка перечислить твитеры twitch.tv, входящие в проект FreeCodeCamp. После того, как функция document.ready добавляет данные в divs (карты bs4), ее необходимо укладывать в карточные колоды в размере 3. Я пытаюсь использовать функцию splitByThree, но она, похоже, не работает. Как это сделать, используя обещания? Буду признателен за любую оказанную помощь.сплит div на 3 после успеха функции getjson и добавление к телу

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>

ответ

1

Для выполнения:

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>

0

Вам нужно переместить функцию splitByThree внутрь функции getDATA. Как только данные JSON извлекаются только после этого, должна быть вызвана функция splitByThree, в противном случае из-за асинхронного характера выполнения функция splitByThree не будет работать корректно, поскольку данные, на которых работает функция splitByThree, являются недопустимыми.

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

     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>'); 
        splitByThree(); 
       }); 
      });    
     }); 

    }; 

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

    }; 
    $(document).ready(readyFN);