所以,我正在使用webgl加载一个3d模型,并有一些代码在显示之前对它执行一些操作。
问题在于这需要几秒钟的时间并完全阻止用户在此期间做任何事情。在此期间你甚至无法滚动,这已经够糟糕了。我听说在javascript中没有多线程这样的东西,但我还是需要它来阻止主线程。
我甚至尝试了一个设置,我将其加载到iframe并使用 window.postMessage 和消息事件监听器,但它似乎是框架的域对于它的javascript也使用相同的线程,所以它不起作用。其他人都有处理CPU密集型代码的解决方案,这样用户就不会做任何事情吗?
答案 0 :(得分:4)
至少目前还没有一个简单的答案
WebWorkers
Web worker在另一个线程中运行JavaScript。不幸的是,他们被允许做的事情非常有限。通常,您所能做的就是来回传递消息。 WebWorker无法触及DOM,无法进行WebGL或制作Canvas(尚未)。您当前所能做的就是联网并将字符串和/或类型化数组传入WebWorker或从WebWorker传递。
如果您正在做的事情需要花费大量时间,可以将其传递回JSON字符串和/或类型化数组中的主线程,这可能对您有用。
状态机
在JavaScript中处理此问题的常用方法是让您的加载程序在多个状态下执行操作,以便您可以将其称为类似
function doALittleMoreWork() {
...
if (theresStillMoreWorkToDo) {
setTimeout(doALittleMoreWork, 16);
}
}
或者那些东西。 doALittleMoreWork
完成了部分工作,然后记住了足够的状态,所以当再次调用时,它可以在停止的地方继续。这就是O3D loader worked。
您可以尝试使用ES6 generators。
生成器有效地让您轻松创建状态机。浏览器还不支持ES6,但有些库可让您现在使用此功能,例如Google Traceur
事实上,如果你写一个像
这样的简单生成器function *foo() {
console.log("do first thing");
yield 1;
console.log("do 2nd thing");
yield 2;
console.log("do 3rd thing");
yield 3;
console.log("do 4th thing");
yield 4;
console.log("do 5th thing");
yield 5;
}
然后通过跟踪#{3}}跟上面的#2
答案 1 :(得分:1)
Web workers API绝对是你需要的