7

上下文

  • 我们有一个基于 Ember 的应用程序,可以处理大量结构化数据(业务流程模型)。
  • 重要的!我们真的很想让我们的应用程序尽可能离线。

需求

虽然我们只需要显示这些数据、编辑它们等等,但雷达中没有显示停止器......

但是现在,我们想对这些模型进行处理:有效性检查、路径查找……以及几种耗时/内存消耗的算法。

问题

我们可以在服务器上处理算法,但这会杀死应用程序的离线模式。

我们曾考虑过让 web worker 避免在后台冻结应用程序和进程算法,但我们面临一个主要问题:将数据传递给 worker 时出现数据重复。至少在计算过程中,使用 Transferable Objects 会使应用程序失去所有权(和数据),因此它似乎不可行。

你会如何处理这个问题?我们唯一的出路是使用我们算法的“类协程”实现吗?有什么线索吗?

4

2 回答 2

5

如果您主要关心的不是在您开发的冗长的 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});
  });
})();

请注意,这是一个非常简化的功能,可以对其进行改进以处理其他与多线程相关的问题——即:等待线程完成(加入)。我希望这段代码可以帮助你。如果您喜欢这种解决问题的方法,请告诉我,如果您愿意,我可以花一些时间改进我的建议。

于 2012-07-04T12:04:05.490 回答
3

很长一段时间过去了,但仍然:解决方案可能是http://jscex.info/

Javascript 本质上是单线程的,它是一种设计选择,因为多线程是一个很难处理的话题,99% 的普通 javascript 开发人员都无法正确处理。

Worker 是获得另一个线程而不阻塞 UI 的唯一方法,但要使它们在没有真正多线程的危险副作用的情况下可用,它们在完全分离的上下文中运行,正如您所注意到的。因此,它们更类似于调用传递命令行参数的外部命令,而不是生成另一个线程。

因此,在“异步”模式下工作是目前唯一的解决方案,但由于您无需等待单击按钮或远程连接完成,您可以绑定的唯一异步事件是计时器的滴答声,它导致糟糕的代码风格困扰着 js 中长时间运行的操作。

然而,有一个小型库,我发现它非常有趣且完全不为人知,它(尽管它的网站很差)能够动态地将编写精美的程序代码“转换”为混乱的计时器和函数固有的异步模型需要:http: //jscex.info/

与在 Windows 3.1 中一样,您只需向浏览器“屈服”($await(Jscex.Async.sleep(50)); )一些时间,使其不会完全冻结。它实际上会在引擎盖下冻结,但如果你频繁地产生,没有人会注意到:) (毕竟,这就是多任务处理仍然在你的 CPU 的每个核心内工作的方式,CPU 是 100% 的非常小的时间片处理一组指令.. 将其缩短到 20 毫秒,没人知道)。

我认为这可以帮助您“生成”类似协程的 JS,而无需实际“编写”此类代码,而是将搞砸它的工作委托给“预编译器”。

于 2012-10-18T03:13:10.423 回答