作为一个教育项目,我正在用 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 来说是完美的。
要修复您的示例,请尝试使用 setTimeout
和 0
来让出控制权。这有效:
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/