使用promises数组和$ .when忽略AJAX错误

我有以下代码从YouTubevideoID数组中获取JSON。 当所有video都存在且查询成功时,它的效果很好。 它发送了几个getJSON请求,当它们全部完成时… $ .when.done()触发,我可以处理结果数据。

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

但是……在最终的应用程序中,我无法控制YouTube中是否仍然存在所有video,我意识到有时列表中的一个(或几个)video可能已被删除…或者ID我从DB得到的不正确。

有没有什么方法可以安全地添加到结果变量只有成功whiteout触发$ .when.fail()的video? 并等待所有查询完成…

我的意思是,我的最终目标是从存在的video(成功检索其数据的那些)中获取数据,并以某种方式忽略那些不存在或不可用的video……我认为不对现在怎么做。

任何想法/方法都会受到欢迎。 TIA!
你可以在这个JSFiddle中找到代码

不幸的是,jQuery没有这个function。

很高兴,你可以很容易地自己实现它。

 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 } 

这是结果的工作JSFiddle 。

在纯粹的JavaScript Promise实现(或Q或其他专用库)中,您可以这样做:

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