上下文
需要
虽然我们只需要显示这些数据,编辑它们等等,雷达中没有显示停止...
但是现在,我们希望对这些模型应用处理:有效性检查,路径查找......以及几种时间/内存消耗算法。
问题
我们可以在服务器上处理算法,但这会破坏应用程序的离线模式。
我们已经考虑过网络工作者以避免在后台冻结应用程序和处理算法,但我们遇到了一个主要问题:将数据传递给工作人员时的数据重复。 使用可转移对象会使应用程序在至少计算期间失去所有权(和数据),因此它似乎不可行。
你会如何处理这个问题?我们唯一的出路是使用算法的“类似协程”实现吗?任何线索?
答案 0 :(得分:4)
如果你主要关心的是在你开发的漫长的javascript处理过程中没有冻结UI,你可以将循环体重构成连续的步骤,这样每一步都可以使用window.setTimeout
来调用它。此技术允许(单个)线程在每次交互之间处理UI事件:
var pr = function(x) {console.log(x)};
var COUNT=3;
// original regular javascript loop
for(var i=0; i<COUNT; i++) {
var msg = "current index is (" + i + ")";
pr(msg);
}
// step-by-step sequential calls
var body = function(i) {
var msg = "non-blocking for: index is (" + i + ")";
pr(msg);
}
nonBlockingFor(body, 4);
函数nonBlockingFor
调用第一个参数(作为函数)作为第二个参数传递的次数。它的定义如下:
// function constructor
var nonBlockingFor = (function() {
function _run(context) {
if(context.idx > context.max) return;
context.fnc(context.idx++);
window.setTimeout((function(){ _run(context)}), 1);
}
return (function _start(ufn, uqt, runId) {
_run({idx: 0, max: uqt -1, fnc: ufn || (function(){}), runId: runId});
});
})();
请注意,这是一个非常简化的功能,可以改进它来处理其他多线程相关的问题 - 即:等待线程完成(加入)。我希望这段代码可以帮到你。如果你喜欢这种解决问题的方法,请告诉我,如果你愿意,我可以花点时间改进我的建议。
答案 1 :(得分:3)
很长时间过去了,但仍然是:解决方案可能是http://jscex.info/
Javascript本质上是单线程的,它是一种设计选择,因为多线程是一个难题,99%的休闲JavaScript开发人员无法正确处理。
工作者是获取另一个线程并且不阻止UI的唯一方法,但是为了使它们可用而没有真正的多线程的危险副作用,它们在完全分离的上下文中运行,正如您所注意到的那样。所以它们更像是调用外部命令传递命令行参数而不是产生另一个线程。
因此,在“异步”模式下工作是目前唯一的解决方案,但由于您没有等待单击按钮或远程连接完成,因此您可以绑定的唯一异步事件是计时器,导致在js中困扰长时间运行的糟糕代码风格。
然而,有一个小型图书馆,我发现它非常有趣并且很不为人知,(尽管它的网站很糟糕)能够动态地“转换”一个精美的程序代码到乱七八糟的计时器和功能异步模型本身需要:http://jscex.info/
在Windows 3.1中,你只需要“屈服”($ await(Jscex.Async.sleep(50));)一段时间到浏览器,这样它就不会完全冻结。它实际上会在引擎盖下冻结,但是如果你经常产生的话,没有人会注意到:)(事后,这就是你的cpu的每个单核内部仍然可以运行多任务处理,这是CPU 100%的非常小的时间片段在一套指令上工作..把它带到20毫秒,没有人能分辨出来。)
我认为这可以帮助你“生成”类似协程的JS,而不是实际“编写”这样的代码,而是委托给“预编译器”弄乱它的工作。