2

この問題に最初に遭遇することはできないと感じていますが、この問題の一般的な解決策を見つけることができないようです。また、そもそもここで間違ったアプローチを取っているのではないかと思います。お知らせ下さい。

さまざまな API (主に OAuth2) とやり取りする Expressjs アプリがあります。リクエストが受信されると、アプリは API からデータを取得するためのアクセス トークンを持っているかどうかを確認します。トークンの有効期限が切れている場合は、新しいトークンが要求されます。

ここで、その間にアプリがまったく同じ API を必要とする 2 番目のリクエストを受信したときに、アクセス トークンの 2 番目の呼び出しを回避したいと考えています。

私がしているのは、特定のキーのコールバックを保存できる「コレクター」を使用することです。キーのコールバックを格納するための最初のリクエストは、タスクの完了後に呼び出すコレクタ コールバックを取得します。後続のすべてのコールバックはキューに入れられ、後でコレクタ コールバックで呼び出されます。

これは単純な Collector クラス (CoffeeScript) です。

# Collect callbacks for tasks and execute all once the job is done
module.exports = class Collector
  constructor: ()->
    @tasks = {}
  add: (key, callback)->
    unless @tasks[key]
      # Initiate callback list for the key with first callback
      @tasks[key] = [callback]
      return ()=>
        # Call all collected callbacks for the key
        (callback.apply {}, arguments for callback in @tasks[key])
        # Reset callback list
        @tasks[key] = null
    else
      # Add callback to existing list
      @tasks[key].push callback
      return false

このクラス内にコールバックを保存することが正しい方法かどうかはわかりませんが、データベース (Redis) を使用するには、コールバックを保存する方法を見つける必要があります…</p>

ジョブが完了したら、複数のコールバックを呼び出すより良い方法はありますか?

4

2 に答える 2

3

コールバックを配列に集約して循環させ、元の呼び出しが完了したときに含まれている各関数を実行してみませんか?

それは次のように単純かもしれません:

var dones = [];

dones.push(function (err, res) { console.log('hoo'); });
dones.push(function (err, res) { console.log('ray!'); });

function whenDone(err, res) { 
   _.each(dones, function (done) { done(err, res); } }); 
}

myWhateverFunction(whenDone);

より美しくしたい場合は、これを任意のデータ構造にラップできます。

于 2012-04-25T10:59:12.323 に答える
0

私はあなたの問題に対する具体的な答えを持っていませんが、非同期モジュールをチェックする必要があります。私はそれが正しい方向への一歩だと思います:https ://github.com/caolan/async

于 2012-04-24T15:11:29.230 に答える