Ignoring AJAX errors with promises array and $.when

心不动则不痛 提交于 2019-11-27 02:57: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 getJSON request, and when all of them are done... the $.when.done() fires and I can process the resulting data.

var
  results  = {},
  promises = [];

$(document).ready(function() {

  var
    vids = [
    'ozj2-bnTL3s',
    'EAZ4Tlt8MQ4',
    'Xn9o7cxqVoA'
    // ,'this-videoid-doesnot-exists'
  ],
  url = 'http://gdata.youtube.com/feeds/api/videos/{{vid}}?v=2&alt=json';

  $.each(vids, function(idx, vid){
    var
      u = url.replace('{{vid}}', vids[idx]),
      p = null;

    p = $.getJSON( u ).done(function(data) {
      results[vid] = data.entry;
    });

    promises.push(p);
  });

  $.when.apply($, promises).done(function(){
    console.log(results);
  });

});

But... In the final app I don't control if all the videos still exists in YouTube, I've realized that sometimes one (or several) of the videos in the list may have been deleted... or the id that I get from the DB is incorrect.

Is there any way that I could safely add to the results variable only the videos that where successful whiteout trigger the $.when.fail()? and waiting that all the queries had finished...

I mean, my final goal is to get the data from the videos that exist (those that its data was successfully retrieved), and, somehow to ignore those that don't exist or where unavailable... and I don't figure right now how to do it.

Any idea / approach will be appretiated. TIA!
You can find the code in this JSFiddle


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/23617895/ignoring-ajax-errors-with-promises-array-and-when

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!