同期っぽい処理

HTML

<div id="term" style="margin:16px;"></div>

JavaScript

/**
 * デバッグ行の追加
 */
function addLine(msg) {
    var term = document.getElementById("term");
    var line = document.createElement("div");
    line.appendChild(document.createTextNode(msg));
    term.appendChild(line);
}


/**
 * ファイルオブジェクト定義
 */
function File(name, byteLength) {
    this.name = name;
    this.isDone = false;
    this.proc = function (callback) {
        var onDone = function () {
            callback.call(this);
        };
        //byteLendthを処理時間に見立てる
        setTimeout(onDone, byteLength);
    };
}


/**
 * ファイル配列を処理キューに追加
 */
function addToQueue(files) {
    addLine("ファイル処理キュー追加開始");
    for (var i = 0; i < files.length; i++) {
        procFile(files, i);
    }
    addLine("ファイル処理キュー追加終了");
}


/**
 * ファイル処理
 */
function procFile(files, idx) {

    var file = files[idx];
    addLine("ファイル処理キューに追加された name=" + file.name);

    //前のファイルの処理が終わるのを待つ
    if (idx > 0) {
        var filePrev = files[idx - 1];
        var timer;
        var timerFunc = function () {
            addLine("一つ前のファイルは処理が終わってる?: name=" + filePrev.name + " isDone=" + filePrev.isDone);
            if (filePrev.isDone) {
                clearInterval(timer); //タイマー解除
                addLine("ファイル処理開始 name=" + file.name);
                file.proc(function () {
                    file.isDone = true;
                    addLine("ファイル処理完了 name=" + file.name);
                });
            }
        };
        timer = setInterval(timerFunc, 500);
    }

    //キュー中の始めのファイルは即処理開始
    else {
        addLine("ファイル処理開始 name=" + file.name);
        file.proc(function () {
            file.isDone = true;
            addLine("ファイル処理完了 name=" + file.name);
        });
    }

}

//ファイルを作って処理開始
var file1 = new File("file1", 1000);
var file2 = new File("file2", 1000);
var file3 = new File("file3", 1000);
var files = [file1, file2, file3];
addToQueue(files);