Javascript 并发控制

标签 javascript concurrency

作为一个教育项目,我正在用 JavaScript 编写(又一个)编辑器风格的实时语法高亮器。

为了让编辑器保持响应,我显然选择让荧光笔异步运行,但是对于我使用的模型,如果在当前荧光笔完成之前输入了某些内容,我需要能够在启动另一个荧光笔之前终止荧光笔,并且知道它在新的开始之前终止。

我正在考虑做如下的事情:

var terminate = false;
var terminated = false;

function work() {
  while(!terminate)
    console.log('working');
  terminated = true;
}

function stop() {
  terminate = true;
  while(!terminated);
  console.log('stopped');
}

setTimeout(work, 0);
setTimeout(stop, 10);

但是这个例子不起作用,我已经尝试使用更多的 setTimeouts 来代替忙碌的等待,但也无济于事。

有没有一种方法可以用 JavaScript 实现这样的系统,或者我应该使用一些替代方法(或两者)?

最佳答案

如果您可以在没有 DOM 访问权限的情况下完成大部分工作,那么这对于网络 worker 来说是完美的。

要修复您的示例,请尝试使用 setTimeout0 来让出控制权。这有效:

var terminate = false;
var terminated = false;

function work() {
  if(!terminate) {
    console.log('working');
    setTimeout(work, 0);
  }
  else terminated = true;

}

function stop() {
  terminate = true;
  if(!terminated) {
      setTimeout(stop,0);
  }
  else console.log('stopped');
}

setTimeout(work, 0);
setTimeout(stop, 100);

编辑

用您的原始代码片段解释问题:Javascript 是单线程的(除非您使用的是网络 worker )。您可以使用事件、回调和 setTimeout 来实现并发的错觉,但您真正在做的是告诉运行时在将来某个时间在单个执行线程上执行您的回调函数。在你的例子中,stop 从未被执行过。在 10 毫秒过期后,它计划运行“下一步”(即,在 work 完成后。由于 work 从未完成,stop 永远不会跑。

所以你想从 javascript 中获得的任何明显的并发性都是合作的。您的工作线程将不得不暂停并明确允许发生“其他事情”以维持幻觉。

关于Javascript 并发控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7338684/

相关文章:

javascript - 从代码中填写网站上的表格

javascript - intel xdk - 如何将项目保存到云端?

android - 处理程序发布的 Runnable 看到错误的对象状态(竞争条件?)

Java任务在网格上的分配和收集

concurrency - Erlang消息接收顺序

javascript - 地理定位在移动浏览器 JavaScript 中不起作用

javascript - 修改后的变量不会显示

javascript - 如果包含某些内容,请删除 HTML 表标签

java - 在运行 JUnit/TestNG 测试套件时,是否有任何*真正的*解决方案来利用多核?

c# - 如何枚举 IAsyncEnumerable<T> 并为每个元素调用异步操作,从而允许每个迭代/操作对并发?