Knockout.jsでdebounceしたかった話
先日、M3 tech meetup! #2 ~フロントエンドの副作用~に参加してきた。
その中のRxJSで時間を制した話で、ユーザー操作のたびに無駄にAPIがコールされるのを、RxJSのdebounce
を使っていい感じにした件なんかが紹介されていた。
この話、個人で作っているサービスのAPI呼び出し回数を減らすのにパクることにした。無料プランで運用しているのでAPIの上限を超えてしまわないか心配だったので。。なんかみみっちい話だけど、趣味のサービスに掛けられるコストは多くない、仕方なし。
RxJSで時間を制した話では、Rx.JSとangular.jsを使っていたのだけれど、自分が作っているサービスはKnoskout.jsを使っているので、Knockout.jsにRx.JSのdebounceに類するものがないか調べたら、ありました。
変更通知を遅延させる|Knockout.js 日本語ドキュメント
rateLimit拡張を使うことで、同じことができるようだ。
通常observable
は変更されるとただちに通知を行うのだけれど、rateLimit拡張を使うことで変更の通知を遅らせることができる。
ko.observable().extend({rateLimit:{timeout: 500, method: "notifyAtFixedRate"}})
↑だと、observable
に 最初に変更があった時点 から500ms後に変更が通知される。
このrateLimit拡張は、methodのデフォルトがnotifyAtFixedRate
なので、省略して↓の形式の呼び出しもできる。
ko.observable().extend({rateLimit:500})
method
には、もう1種類notifyWhenChangesStop
も存在して、こちらはobservable
に 指定した期間変更がなければ 通知が飛ぶ。
rateLimit拡張は、observable以外にもobservable arrayやconputed observableなどの、他のobservableに対応している。すばらしい。
追記
Knockout.jsのrateLimit拡張は、バージョン3.1.0以降の呼び名で、以前はthrottle拡張という名前だったようだ。
ちなみに、lodashにも_.throttleというのがあって、対象の関数の実行を指定期間に1回に制限するものらしい。これはrateLimit拡張のnotifyAtFixedRateの動作に該当する。
そして、_.debounceも存在して、こちらは最後に実行されてから指定時間経過後に関数を実行する。これはrateLimit拡張のnotifyWhenChangesStopの動作に該当する。
で、興味深いのがRx.JSのdebounceは、動作的にはlodashの_.debounceではなくて、_.throttleのほうだということ。lodashとRs.JSの間でねじれが起きてる。
ちなみに、debounceというのは元々ハードウェアだか電子回路の用語だそうです。 debounceという新しい単語を知ることで、連鎖的に知識が広がるいい機会でした。
Latest post:
- OpenWhiskのScala sbtプロジェクトのgiter8テンプレートを作った
- OpenWhisk+Scalaで作るServerless Architectureとっかかり
- BluemixにPlayframeworkアプリケーションをデプロイする
- sbt、Giter8を統合するってよ
- Scala 2.12.0でSAM型