简体   繁体   中英

Javascript Concurrency Control

As an educational project, I'm writing (yet another) editor-style live syntax highlighter in JavaScript.

To keep the editor responsive I obviously opted to have the highlighter run asynchronously, however with the model I'm using I need to be able to terminate a highlighter before starting another if something is typed before the current highlighter finishes, and know that it's terminated before the new one starts.

I was thinking of doing something like the following:

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);

This example however doesn't work, and I've tried using more setTimeouts in place of the busy waiting to no avail, either.

Is there a way to implement such a system in JavaScript or should I use some alternative (or both)?

If you can do much of your work without DOM access, this would be perfect for web workers.

To fix your example, try yielding control using setTimeout with 0 . This works:

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);

edit

To explain the problem with your original code snippet: Javascript is single-threaded (unless you are using web workers). You can use events, callbacks, and setTimeout to achieve an illusion of concurrency, but what you are really doing is telling the runtime to execute your callback function at some future time on the single execution thread. In your case, stop was never being executed. After the 10 ms expired, it was scheduled to run 'next' (ie, after work finished. Since work never finished, stop could never run.

So any apparent concurrency you want to get out of javascript will be co-operative. Your worker thread will have to pause and explicitly allow "other stuff" to happen to maintain the illusion.

In this case consider to use Workers . Most of modern browsers supports them. Without workers there is no really concurency in javascript (which is good) - all is done in one thread.

A lot of setTimeout() calls is a killer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM