0

データベースから多くのデータをロードし、それに基づいていくつかの結果を計算する koa にエンドポイントがあります。これには数秒かかる場合があります。

ブラウザがリクエストをキャンセルした場合、リクエストはどうなりますか? ブラウザのタブが閉じられるなど。

たとえばcache.c、ブラウザーがキャンセルした場合や、koa がこの要求に対して開始したアクションを単純に停止するほどスマートな場合でも、入力されますか?

const cache = {}
router.get('/data', function *(next) {

  if (cache.c) return this.body = cache.c

  // somewhere here the browser cancels the request
  //---
  const a = yield db.getA()
  const b = yield db.getB()
  cache.c = yield calculateC(a,b)
  //---

  this.body = cache.c

})
4

1 に答える 1

1

ジェネレーター関数は、リクエスト ソケットがいつ閉じられるか (ユーザーがタブを閉じるなど) に関係なく、全体として生成/評価されます。

ソケットが閉じたという理由だけでジェネレーターの実行を停止することは、Koa が想定できることではありません。

たとえば、Koa がジェネレーターの実行を自動停止し、ユーザーがyield query('ROLLBACK')db 接続をクリーンアップする前にソケットを閉じたとします。これで、失敗した db 接続がプールにスタックしました。それよりももっと良い理由があるかもしれません。

つまり、Koa はジェネレーター関数を終了するまで実行し続けます。終了すると、応答がミドルウェアを介して戻ってきて、ソケットが閉じられているためどこにも行かない Koa の制御に戻ります。

独自の短絡動作を実装できるように、ユーザーがいつタブを閉じたかを知りたい場合は"close"、リクエスト ソケットでイベントをリッスンできます。

const cache = {}
router.get('/data', function *(next) {
  if (cache.c) return this.body = cache.c;

  var closed = false;
  this.request.socket.on('close', function() {
    closed = true;
  });

  if (closed) return;
  const a = yield db.getA();
  if (closed) return;
  const b = yield db.getB();
  if (closed) return;
  cache.c = yield calculateC(a,b);

  this.body = cache.c;
})
于 2015-12-20T12:59:34.817 に答える