【发布时间】:2021-02-04 21:59:23
【问题描述】:
Promise 的新手 - 尝试找出逻辑。
我正在尝试自动抓取 youtube 预览缩略图,如 this answer 建议:
const youtubeAnimation = id => {
return fetch(
`https://cors-anywhere.herokuapp.com/https://www.youtube.com/results?search_query=${id}&sp=QgIIAQ%253D%253D`,
{ headers: {} }
)
.then(r => r.text())
.then(html => {
const found = html.match(
new RegExp(`["|']https://i.ytimg.com/an_webp/${id}/(.*?)["|']`)
);
if (found) {
try {
const url = JSON.parse(found[0]);
return url;
} catch (e) {}
}
throw "not found";
})
.catch(e => {
return false;
});
};
我将 youtube ID 存储在视频属性的容器中,然后对页面上的单个视频执行此操作:
youtubeAnimation($('.video').attr('youtube')).then(function (value) {
$('<img class="videopreview" src="' + value + '">').insertBefore($('.video'));
});
但我需要能够在页面上使用可变数量的$('.video') 元素来运行它。我试过把它放在每个循环中:
$(".video").each(function () {
youtubeAnimation($(this).attr('youtube')).then(function (value) {
$('<img class="videopreview" src="' + value + '">').insertBefore($(this));
});
});
但这只是将预览缩略图添加到最后一个$('.video') 元素。使用 console.log 进行测试时,我可以看到所有预览图像都被发现,但只有最后一个图像应用于最后一个元素。在继续下一个元素之前,我需要以某种方式暂停 each 循环,直到 youtubeAnimation 完成它的工作。
要使这一切顺利进行,还需要哪些额外步骤?另外,答案将youtubeAnimation 作为常量而不是函数的原因是什么?
【问题讨论】:
-
尝试
.then((value) =>而不是.then(function (value) {- 所以this是正确的 -
顺便说一句,你不能像你想象的那样等待 .each 或 .forEach 中的 promise,即你不能使用 .forEach/.each 来执行一系列异步一个接一个的任务 - 只是想澄清你的问题不是等待承诺,它是
.then中的this不是你所期望的 -
@JaromandaX 哇,它成功了! TIL 关于箭头函数。感谢您的洞察力,我要去研究了。如果问题是
this,是否也可以使用常规函数并将$(this)存储在变量中,然后在promise 中调用它?当我尝试时它不起作用。 -
你是否像
.each(function (value) { var $this = $(this); youtubeAnimation(... etc一样存储了$(this) -
@JaromandaX 关闭,但我没有包括
var或value那里。它是.each(function () { this = $(this)...。我无法检查以确认是否可以解决问题,因为我现在受到速率限制。但是理论上,这应该是解决这个问题的另一种方式吧?
标签: javascript jquery promise youtube each