Ignoring AJAX errors with promises array and $.when

后端 未结 2 469
再見小時候
再見小時候 2020-12-09 21:32

I have the following code that gets the JSON from an array of YouTube video ids. It works great when all the videos exists and the query is successful. It sends several getJ

相关标签:
2条回答
  • 2020-12-09 22:03

    In a purely javascript Promise implementation (or a specialised library like Q or another), you could do this:

    function getVideo(id) {
      return new Promise(function(resolve, reject) {
        var request = new XMLHttpRequest();
        request.open('GET', 'url = 'http://gdata.youtube.com/feeds/api/videos/' + id + '?v=2&alt=json');
        request.onload = function() {
          if (request.status == 200) {
            resolve(request.response); //we get the data here. So, resolve the Promise
          } else {
            reject(Error(request.statusText)); //if status is not 200 OK, reject.
          }
        };
    
        request.onerror = function() {
          reject(Error("Error fetching data.")); //error occurred, reject the Promise
        };
    
        request.send(); //send the request
      });
    }
    
    function fetchVideos() {
      var vids = [
        'ozj2-bnTL3s',
        'EAZ4Tlt8MQ4',
        'Xn9o7cxqVoA'
        // ,'this-videoid-doesnot-exists'
      ]
      var promises = [];
      for (var i in vids) {
        promises.push(getVideo(vids[i]));
      }
      Promise.all(promises).then(function(dataArr) {
        dataArr.forEach(function(data) {
          console.log(data.entry);
        });
      }).catch(function(err){
          console.log(err);
      });
    }
    
    0 讨论(0)
  • 2020-12-09 22:11

    Unfortunately, jQuery doesn't come with this functionality.

    Gladly, you can implement it yourself pretty easily.

    var url = 'http://gdata.youtube.com/feeds/api/videos/{{vid}}?v=2&alt=json';
    function getVideo(vid){
        var u = url.replace('{{vid}}', vid);
        return $.getJSON( u ).then(function(res){
             return {video:vid,result:res.entry};
        });
    }
    var promises = ['ozj2-bnTL3s','EAZ4Tlt8MQ4',"doesn'texist"].map(getVideo);
    
    some(promises).then(function(results){
        for(var i = 0; i < results.length; i++) {
            console.log(results[i]); // log
        }
    });
    
    
    
    // get a hook on when all of the promises resolve, some fulfill
    // this is reusable, you can use this whenever you need to hook on some promises
    // fulfilling but all resolving.
    function some(promises){
        var d = $.Deferred(), results = [];
        var remaining = promises.length;
        for(var i = 0; i < promises.length; i++){
            promises[i].then(function(res){
                results.push(res); // on success, add to results
            }).always(function(res){
                remaining--; // always mark as finished
                if(!remaining) d.resolve(results);
            })
        }
        return d.promise(); // return a promise on the remaining values
    }
    

    Here's a working JSFiddle of the result.

    0 讨论(0)
提交回复
热议问题