Synchronous invocation in JavaScript, part 2: execution dissected

Let’s review the process definition and process constructor from part 1:


     1  function proc(processDef) {
     2      var process = processDef();
     3
     4      function driver() {
     5          var pseudoBlockingCall = process.next();
     6
     7          pseudoBlockingCall(driver);
     8      }
     9
    10      return driver;
    11  }

    12  var driver = proc(function() {
    13      dump("Going to bed...\n");
    14      var pseudoBlockingCall = function(driver) {
    15          window.setTimeout(driver, 3000);
    16      });
    17      yield(pseudoBlockingCall);
    18      dump("Sigh, I only slept three seconds.\n")
    19  });

    20  driver();

The conversation among the three actors (process definition, process driver and process costructor) goes like this. Notice the many control transfers, and remember that executing the process definition to get the process (at line 2) returns a generator—that’s why process can be entered and exited many times at intermediate stages.

(line) main constructor driver process
12 driver = proc(…
02 var process = fn()
10 return driver
20 driver()
05 process.next()
(process.next() in the driver is called for the first
time. Control goes to the process, and the process advances until the
first yield().)
13 dump(“Going to bed…\n”);
14 pseudoBlockingCall = …
08 yield(pseudoBlockingCall)
(yield() causes control to pass back to the
driver, and yield()’s argument (the pseudo-blocking
function) becomes the return value of
process.next().)
17 pseudoBlockingCall = process.next()
07 pseudoBlockingCall(driver)
15 window.setTimeout(driver, 3000);
05 process.next();
(The pseudo-blocking function is executed and told to invoke
the driver again when it’s finished.)
18 dump(“Sigh, I only slept three seconds.\n”);
(The driver has been invoked again, and the process is told to
advance to the next yield() (or to the end).)

Not bad for less than twenty lines of code…

In the next part, we’ll see how to make conversation more lively by allowing pseudo-blocking functions to compute and return values.

Articles in this series:

  1. Part 1: Problem and basic solution
  2. Part 2: Execution dissected
  3. Part 3: Returning values
  4. Part 4: Error handling