Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
465 views
in Technique[技术] by (71.8m points)

jquery - Ignoring AJAX errors with promises array and $.when

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...