tohokuaikiのチラシの裏

技術的ネタとか。

Deferredの再帰

JavaScript - 再帰 with promise pattern - Qiita再帰

var counter = 0;
function fact(n) {
    var d = $.Deferred();
    if (n > 1){
        console.log("continue",n, ++counter);
        fact(n -1).done(function(result){
            console.log("done", n,result, ++counter);
            d.resolve(result * n);
        });
    } else {
        console.log("end",n, ++counter);
        d.resolve(n);
    }
    console.log("end after", n, ++counter);
    return d.promise();
}

fact(5).done(
function(result){
console.log("THE END", result, ++counter);
});

Result:

continue 5 1
continue 4 2
continue 3 3
continue 2 4
end 1 5
end after 1 6
done 2 1 7
end after 2 8
done 3 2 9
end after 3 10
done 4 6 11
end after 4 12
done 5 24 13
end after 5 14
THE END 120 15

ここまで書いてようやく理解できた。

ポイントは、

  1. nがクロージングされていること
  2. 最後にresolveされたのがpromiseしてることでコールバックが掛かること(必ず先にpromiseしないとダメだと思ってた)
  3. 最後に1個resolve→doneされたものが、逆に駆け上がっていく感じ(先に作られたDeferredオブジェクトが後で発火する)

という感じかな?

まだよく理解しきれてない。