gpt4 book ai didi

javascript - 如何在 $.each() 循环中保持 $.ajax() 异步但对每次迭代的结果使用react

转载 作者:搜寻专家 更新时间:2023-11-01 04:16:37 25 4
gpt4 key购买 nike

我在处理一些愚蠢的架构时遇到了麻烦,因为我很愚蠢。我正在尝试循环播放发布到 Reddit 的 YouTube 视频,提取 URL 并将它们处理成 .m3u 播放列表。

完整代码在 Subreddit to YouTube Source Bookmarklet - Play YouTube music from subreddits in Foobar with foo_youtube

在某些时候,我想到我可以检查每个 URL 以查看视频是否已失效,并在它们被删除时提供替代方案。

所以我向 YouTube API 发出 AJAX 请求,如果出现错误,我应该对其使用react并更改该项目的 URL。

但问题是它只有在 AJAX 不是异步的情况下才有效——这需要很多秒,在此期间页面会卡住。

我想让 AJAX 异步,但我不知道应该如何构建我的代码。

这是现在的伪代码:

var listing = // data from reddit API
$.each(listing, function(key, value) {
var url = // post URL from reddit posts listing
// ( "http://youtu.be/XmQR4_hDtpY&hd=1" )
var aRegex = // to parse YouTube URLs
// ( (?:youtube(?:-nocookie)?.com/....bla...bla )
var videoID = // YouTube video ID, extracted with regex
// ( "XmQR4_hDtpY" )
var itemArtist = // parsed from reddit posts listing
// ( "Awesome Artist" )
var itemTitle = // parsed from reddit posts listing
// ( "Cool Song (Original Mix)" )
var itemURL = // url, further processed
// ( "3dydfy://www.youtube.com/watch?v=XmQR4_hDtpY&hd=1" )

$.ajax({
type: "HEAD",
url: "https://gdata.youtube.com/feeds/api/videos/" + videoID,
error: function() {
// If it's no longer available
// (removed, deleted account, made private)
deadVid++; // chalk up another dead one, for showing progress
itemURL = // dead videos should get a different URL
// ( "3dydfy-search://q=Awesome%20Artist%20Cool%20Song....." )
}
});

// further process itemURL!
// at this point I want itemURL changed by the .ajax()'s error callback
// but I'm trying to keep the requests async
// to not jam the page while a hundred HTTP requests happen!
if (condition){
itemURL += // append various strings
}
// Write the item to the .m3u8 playlist
playlist += itemURL + '\n';
}// end .each()

最佳答案

基本上你想知道

  • 错误是什么以及
  • 当每个ajax请求完成时

如果将错误插入列表,结果将在最后准备好(当然不能保证顺序)。

对于第二部分,如果您保留从每个 $.ajax 返回的 ajax promise 数组,您可以使用 $.when 并使用 always() 等待它们全部完成

作为一个基本示例(删除了其他细节):

var listing = {}; // data from reddit API
var promises = [];
var results = [];
$.each(listing, function(key, value) {
// [snip]
promises.push($.ajax({
type: "HEAD",
url: "https://gdata.youtube.com/feeds/api/videos/" + videoID,
error: function() {
//[snip]
results.push({
itemArtist: itemArtist,
videoID: videoID,
url: itemURL});
}
});
);
}
// Wait for all promises to complete (pass or fail)
$.when.apply($, promises).always(function(){
// process list of failed URLs
});

对任何打字错误深表歉意。这是直接编码到答案中的,但您明白了。

我注意到您提到了 100 多个请求,但浏览器一次只允许少数通过,因此不需要额外处理。

如果 always 不起作用,您可以添加自己的延迟对象,这些对象在成功 失败时解析:

var listing = {}; // data from reddit API
var promises = [];
var results = [];
$.each(listing, function(key, value) {
var deferred = $.Deferred();
promises.push(deferred.promise());
// [snip]
$.ajax({
type: "HEAD",
url: "https://gdata.youtube.com/feeds/api/videos/" + videoID,
complete: function(){
// resolve on success or fail
deferred.resolve();
},
error: function() {
//[snip]
results.push({
itemArtist: itemArtist,
videoID: videoID,
url: itemURL});
}
});
);
}
// Wait for all promises to complete (pass or fail)
$.when.apply($, promises).always(function(){
// process list of failed URLs
});

2015 年 12 月更新

这是另一种将并行 promise 链接在一起的很酷的方法,无需使用数组(只要您不需要传递给回调的数据值):

简化代码:

   var promise;   // Undefined is also a resolved promise when passed to $.when()
$.each(listing, function(key, value) {
// Each new Ajax promise is chained, in parallel, with the previous promise
promise = $.when(promise, $.ajax({...}));
});
// When they are all finished, fire a final callback
$.when(promise).always(function(){
// All done!
});

这受到了一些批评,主要来自认为它“不干净”的人,但对于简化并行 promise 代码而言,权衡是最小的。

当我看到有人使用 promise = promise.then(newpromise) 按顺序链接事件时,我发现这是可能的。经过一些试验后,我发现我可以使用 promise = $.when(promise, newpromise)

并行执行相同的操作

关于javascript - 如何在 $.each() 循环中保持 $.ajax() 异步但对每次迭代的结果使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26678572/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com