基本上就是这样。我想在同步函数中使用 jQuery 的每个函数。 不过,据我所知。它不起作用,因为每个函数只是检查返回值是否为 false 以打破循环。它不会检查它是否是一个 promise ,然后将其设置为等待它得到解决。有没有一种简单的方法可以使 jQuery 的每个函数与 Promise 同步?
我目前有一个替代方案,即创建一个迭代元素的 for 循环,但写起来有点长,所以我想尽可能避免这种情况。
这是一个 fiddle : https://jsfiddle.net/3pcvqswn/2/
function sleep(ms)
{
return new Promise(resolve => setTimeout(resolve, ms));
}
$(document).ready(function()
{
(async () =>
{
console.log("This method works, but its lengthy to write");
var elements = $("div");
for(var index = 0; index < elements.length; index++)
{
var el = $(elements.eq(index));
console.log("The content is: " + el.text());
await sleep(1000);
}
console.log("This method doesn't work, but its easier to write");
$("div").each(async (index, el) =>
{
console.log("The content is: " + $(el).text());
// doesn't wait
await sleep(1000);
});
})();
});
我决定使用 for of
,但同时具有索引和元素回调的更准确的解决方案是
Object.entries($("div")).forEach(async ([index, el]) =>
{
console.log("row ", index, el);
});
最佳答案
否 - jQuery 的 .each
的工作方式与 forEach
类似。每个回调都会被一个接一个地触发,如果回调返回一个 Promise(例如,如果它是一个异步函数),则不会等待它 - 它的工作方式类似于
callback();
callback();
callback();
除非回调中的某些内容阻塞(如果您使用良好的编程实践,则不应出现这种情况),回调中的任何异步初始化都不会导致进一步的回调等待该异步操作完成.
但是 jQuery 对象是可迭代的,因此使用简洁的 for..of
来迭代元素是很简单的:
const sleep = ms => new Promise(res => setTimeout(res, ms));
(async () => {
for (const elm of $("div")) {
console.log("The content is: " + $(elm).text());
await sleep(1000);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>text 1</div>
<div>text 2</div>
<div>text 3</div>
在我看来,这一点也不冗长。
为了在循环中使用 await
,循环必须是 for
循环(for..in、for..of 或 for( let i = ...),或者需要构造循环的迭代机制,以便等待最后一个回调解析,例如使用 reduce
:
const sleep = ms => new Promise(res => setTimeout(res, ms));
[...$("div")].reduce(async (lastProm, elm) => {
await lastProm;
console.log("The content is: " + $(elm).text());
await sleep(1000);
}, Promise.resolve());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>text 1</div>
<div>text 2</div>
<div>text 3</div>
旁注几乎不值得一提 - 我之前说过在 .each
中使用 await
不起作用
Unless something in the callback blocks (which it shouldn't if you're using decent programming practices)
如果您编写了一个昂贵且愚蠢的阻塞版本的 sleep
,它会消耗所有资源直到到达下一秒,那么“可能”在循环内等待,但永远不应该这样做:
const sleep = ms => {
const now = Date.now();
while (Date.now() - now < ms) {}
}
正确使用 Promise 会更好。
关于javascript - 是否可以在 jQuery.each() 内部使用同步 promise sleep ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60592118/