我在一个web应用中,有一个长时间取用、线程阻塞的功能,在其执行过程中,我想显示一个动画图标。在其执行过程中,我想显示一个动画图标。我想使用Window.RequestAnimationFrame()requestAnimationFrame(). 我的工作来源是。
https:/developer.mozilla.orgen-USdocsWebAPIwindowrequestAnimationFrame。
https:/developer.mozilla.orgen-USdocsLearnJavaScriptAsynchronousTimeouts_andintervals。
https:/wiki.selfhtml.orgwikiJavaScriptWindowrequestAnimationFrame。
我知道,我需要一个函数--我把它叫做 animateLoadingIcon() - ,以更新我的绘图。在它的函数体中,我最后必须调用 requestAnimationFrame(animateLoadingIcon) 来启动视图的递归更新。
在下面找到函数animateLoadingIcon,它根据调用后所经过的时间,计算图标的旋转角度。
function animateLoadingIcon() {
rotateCount = (new Date().getTime() - starttime) / 3;
if (rotateCount > 359) {
rotateCount %= 360;
}
divLoadingIcon.style.transform = 'rotate(' + rotateCount + 'deg)';
requestedAnimationFrame = requestAnimationFrame(animateLoadingIcon);
}
我原本想执行的函数是calc(),其中调用了animateLoadingIcon()。
function calc() {
let randomMills = Math.random()*6000;
console.log("Start with duration: " + randomMills +"ms.")
starttime = new Date().getTime();
let recentTime = new Date().getTime();
let i = 0;
animateLoadingIcon();
while (recentTime < starttime+randomMills) {
i++;
isPrime(i);
recentTime = new Date().getTime();
}
cancelAnimationFrame(requestedAnimationFrame);
}
我希望当我点击按钮时,轮子能转动,当离开while-loop时,轮子能停止。然而,它却没有。谁能指出我的错误?
请看下面一个jsfiddle的例子https:/jsfiddle.net71vqarLs8
窗口.请求动画帧 会是一个更好的解决方案,也是 "正确 "的方式。
使用承诺和 asyncawait使用setTimeout循环代替while循环,这样每次对isPrime的调用和每次循环迭代都在事件循环中延时,并允许动画在其间执行。
jsfiddle演示。https:/jsfiddle.netcxews089
await new Promise(res => {
var loop = () => {
var tid = setTimeout(() => {
if (recentTime < starttime + randomMills) {
i++;
isPrime(i);
recentTime = new Date().getTime();
loop()
} else {clearTimeout(tid);res();}
}, 0)
};
loop()
});
不太美观,肯定可以写得更优雅,但可以用。 可能一个异步函数循环也可以作为一个单行的等价物。当然会有开销,你可能想对isPrime或其他任何你要调用的函数进行分块调用。
感谢所有有用的意见。关于将线程阻塞的while-loop外包给worker的提示很有针对性。
我现在基本上只调用
function calc() {
animateLoadingIcon();
worker.postMessage([randomMills, starttime])
}
而当worker发出准备好的事件时,我就执行。
worker.onmessage = function (e) {
cancelAnimationFrame(requestedAnimationFrame);
}
这就把阻塞代码放到了一个单独的线程中, 而requestAnimationFrame可以在主线程中安然运行。