直列setInterval 直列setTimeout の試み

実際には、関数の呼び出しが多すぎるので、精度悪い。使えないという前提で。
タイマー(setInterval か setTimeout)に仕込んだコールバック関数がクリアされた時点で、次のコールバック関数を開始する。 とかそういうの。無理やり関数っぽくしてみた。

timer.js

function timer (f, interval, timerOption) {
    var queue, _timerOption, that, helper;
    queue        = [];
    _timerOption = 'timeout';

    helper = function () {
            var job, timerID, clearTimer;
            if (queue.length > 0) {
                job    = queue.shift();
                timerID = job.setTimer(function () {
                        job.func(clearTimer);
                }, job.interval);
                clearTimer = function () {
                        ((job.setTimer === setTimeout)
                                ? clearTimeout
                                : clearInterval)(timerID);
                        that();
                };
            }
    };

    that = function (f, interval, timerOption) {
            var setTimer;
            interval = (typeof interval === 'undefined') ? 1000 : interval;
            setTimer = (timerOption === _timerOption)
                     ? setTimeout
                     : setInterval;

            if (arguments.length === 0) {
                helper();
            } else if (typeof f === 'function' && interval === interval - 0) {
                queue.push({
                    func     : f,
                    interval : interval,
                    setTimer : setTimer
                });
            }

            return that;
    };

    return that(f, interval, timerOption);
}

if (exports) {
	exports.timer = timer;
}

timer.demo.js

var timer = require('./timer').timer;
var t, i = 0;

t = timer(function (clearTimer) {
        if (i > 10) {
            console.log('start wait');
            return clearTimer();
        }
        console.log(i);
        i++;
}, 1000)(function (clearTimer) {
        console.log('stop wait');
        return clearTimer();
}, 2000, 'timeout')(function (clearTimer) {
        if (i > 20) {
            console.log('FINISH');
            return clearTimer();
        }
        console.log(" * " + i);
        i++;
}, 1000);

t();

やってることは、

  1. 0 から 10 まで、1秒間隔でカウントアップ
  2. 2秒ウェイト
  3. 11 から 20 まで、1秒間隔でカウントアップ
  4. おわり

コールバック関数の引数 clearTimer を実行したタイミングで 次のコールバック関数が実行される