Promise + Generator

javascripter さんの記事ではPromise実装としてjQueryのを使用しているけど、Fx では DOM Promise が使えるので、それに合わせて書きなおしてみた。

serialExperimental.js

function serialExperimentalProceed (generator) {
  var thread = generator();
  serialExperimentalProceed.proceed(thread);
}
serialExperimentalProceed.proceed = function proceed (thread) {
  var { done, value } = thread.next();
  if (done)
    return;

  if (value instanceof Promise)
    value.then(
      result => {
        proceed(thread);
      },
      error  => {
        console.error(String(error));
      });
  else
    proceed(thread);
};

function async (ms, func) {
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      try { 
        func();
        resolve();
      } catch (e) {
        reject(e);
      }
    }, ms);
  });
}

serialExperimentalProceed(function * () {
  var startTime = Date.now();
  echo("Start: " + startTime);
  yield async(1000, () => {
    echo("Hello");
  });
  echo("+ " + (Date.now() - startTime));
  yield async(1500, () => {
    echo("Serial Experimental");
  });
  echo("+ " + (Date.now() - startTime));
  yield async(1500, () => {
    echo("Proceed");
  });
  echo("End: + " + (Date.now() - startTime));
});
echo("start");

lain.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Serial Experimental proceed</title>
  <style>
#out { line-height: 1.5; }
#out > p { margin: 0; }
  </style>
</head>
<body>
<h1>Serial Experimental Proceed</h1>

<pre id="out"></pre>
<script>
var out = document.getElementById("out");

function echo (...args) {
  var msg = args.join(" ");
  var p = document.createElement("p");
  p.appendChild(document.createTextNode(msg));
  return out.appendChild(p);
}
</script>
<script src="serialExperimental.js"></script>
</body>
</html>