モナドと約束についてのダグラス・クロクフロドの話を見ている間、私は52:40に尋ねられた質問に興味がありました。Monadsを使用してウォッチドッグタイマーを実装すると、promiseが保持されるか、失敗関数が呼び出される前に定義可能な期間だけ保留状態で存続できるようになります。このパターンには一般的に受け入れられている名前がありますか?
2 に答える
そうじゃないよ、ジェイソン。GitHub での Crockford の実装を見ると、その動作に適したフックがありません。
とはいえ、典型的な Promise パラダイム内には、Crockford コードが許可するものよりも多くのオプションがあります。
AJAX ライブラリを見てください。多くの人が知らないにもかかわらず、多くの AJAX ライブラリ (jQuery を含む) が promise を返します。
彼のコード内でそれを行うには.break
、約束の引数で送信された時間に基づいて、約束のタイマーを持つ句をフックできます。
それ以外の場合は、次のようなことができます。
var vow = VOW.make(),
last_promise = vow.when()
.when()
.when()
.when() /*...*/;
(function () {
var vow = VOW.make(),
time_over = false,
time_limit = 30 * 1000,
timer_handle,
success = function (value) {
if (time_over) { vow["break"]("Time's up!"); }
else {
clearInterval(timer_handle);
vow.keep(value);
}
};
trailing_promise.when(success, /* fail */);
return vow.promise;
}()).when(/* ... */)
.when()
.when();
そのようなものは、そこに与えられたものでうまくいくはずだと思います。
done
個人的には、講演を見て彼の実装を読んだ後、線形キュー関数 ( 、fail
またはsuccess/fail
その他)を維持するという約束を好むと思いますready/fail
が、私が見たほとんどのライブラリは一時キュー ( when
、next
、など)を作成します。約束とは別に。
ここには 2 つの競合するキューがあります。イベントにサブスクライブするもの (.addEventListener
アクションが発生すると、すべてのリスナーが同時に呼び出されるなど) と、次の結果の最終的なリターンにサブスクライブするもの (サブスクライブしている何かをリッスンするなど) eventListner)。
Crockford の最小限の実装では、リスナーを 1 つしか持てず、サブスクライバーが前のサブスクライバーの最後のサブスクライバーをリッスンするようなものです...
...そして、複数の命令をチェーンして同じキューで発生させる唯一の方法は、戻り値をキャッシュすることです。
var level_0 = VOW.make(),
level_1 = level_0.when(/* ... , ... */),
level_2 = level_1.when(/* ... , ... */);
level_1.when(/* more stuff */);
level_1.when(/* even more */);
level_2.when()
.when()
.when();
// ...eventually.......
level_0.keep("stuff");
私はjQueryのDeferredメソッド(ステートメントが見つかりませんがモナディックだと思います)で遊んでいますが、これはうまくいくようです(デモ)(これは簡単すぎるようです)
function watchdog(promise, time) {
setTimeout(function() {
promise.abort();
}, time);
};
JSFiddle でAjax テスト フックを使用した例:
console.log("Waiting 2,000ms for something we think will take 3,000ms to return");
watchdog(
$.post('/echo/html/', { delay: 3 })
.done(function() {console.log("Got It!");})
.fail(function() {console.log('took too long (but I knew that)!');})
.always(function() {console.log('Cleaning up no matter what');})
, 2000);
console.log("Waiting 3,000ms for something we think will take 2,000ms to return");
watchdog(
$.post('/echo/html/', { delay: 2 })
.done(function() {console.log("Got It (but I knew that)!");})
.fail(function() {console.log('took too long!');})
.always(function() {console.log('Cleaning up no matter what');})
, 3000);
これは、生成されるログです。
Waiting 2,000ms for something we think will take 3,000ms to return
Waiting 3,000ms for something we think will take 2,000ms to return
took too long (but I knew that)!
Cleaning up no matter what
Got It (but I knew that)!
Cleaning up no matter what