エラーを throw した時の Deferred の処理順
Spider Monkey で下記のサンプルを実行すると・・・
var d = new Deferred(); d.addCallbacks(throw_error, partial(error, 'debug0')); d.addCallback(increment); d.addCallbacks(increment, partial(error, 'debug1')); d.addCallback(increment); d.addCallback(increment); d.addCallback(throw_error); d.addCallback(increment); d.addCallbacks(increment, partial(error, 'debug2')); d.addCallback(increment); d.addErrback(partial(error, 'debug3')); d.callback(1); function increment (num) { print(num); return num + 1; } function error (message, e) { print(message + ':' + e.message); return 0; } function throw_error (num) { throw new GenericError('error!!'); }
下記のように出力される。
debug1:error!! 0 1 debug2:error!! 0
表にすると、こんな感じにチェーンが形成されている。
i | call back | error back |
---|---|---|
0 | throw_error | partial(error, 'debug0') |
1 | increment | |
2 | increment | partial(error, 'debug1') |
3 | increment | |
4 | increment | |
5 | throw_error | |
6 | increment | |
7 | increment | partial(error, 'debug2') |
8 | increment | |
9 | partial(error, 'debug3') |
0 行目の throw_error でエラーが throw されて 2行目の、partial(error, 'debug1') が実行される。
そのまま、3 行目、4行目 の increment が実行される。
次に、5行目の throw_error でエラーが throw されて、7行目の、partial(error, 'debug2') が実行される。
最後に、8行目の increment が実行されて終わり。
「d.callback(1);」を「d.errback(new GenericError('error!!'));」に変更すると、下記のような出力となる。
debug0:error!! 0 1 2 3 debug2:error!! 0
error back のチェーンだけ実行し続けたい場合は、error back に登録されいてる関数内で、エラーを throw し続ければ良い。
うーん、我ながら、解り難い説明だ・・・。
参考URI
Collection & Copy - Deferredチェーン、非同期処理の逐次実行
MochiKit.Async - manage asynchronous tasks
Twisted ドキュメント: Deferred リファレンス
参考書籍
WEB+DB PRESS Vol.37
Rediscover the JavaScript【最終回】MochiKitを極める! …Webプログラミング編……舘野祐一