2016-09-07 4 views
0

私はここで同様の問題を検索しようとしましたが、驚いたことに、すでに投稿されているものは見つかりませんでした。expressjsのコールバック間でルートパラメータを渡す最善の方法

私はexpressjs v4のフレームワークを使用し、私はこのような私のルートを構築しています:あなたは上記を参照できるように、私は今usersモジュールルックスlet users = require('./modules/users')

を必要としています

'use strict'; 

let express = require('express'); 
let router = express.Router(); 
let users = require('./modules/users'); 

router.post('/',users.add); 

router.put('/edit/:id',users.edit); 

(さんが言わせて)このように:あなたが気づくことができる

'use strict'; 
let usersDbModule = require('...'); 

let users = { 
    'add': (req, res, next) => { 
     let callback = (err, record) => { 
      //...do something 
      users.function1(record) 
     } 
     usersDbModule.save(req, callback); 
    }, 
    'function1': (record) => { 
     users.function2() 
    }, 
    'function2':() => { 
     //...do something with next() function 
    } 
} 

、最初のコードブロックからそのルータは、モジュールのadd機能を使用しています。 addは標準的な高速ミドルウェア機能ですが、今は状況がより複雑になっています。

あなたが見ることができるように、add機能は、今、私は別の関数からのいくつかの複雑なコールバック呼び出しを行うとのは、最後に私がfunction2nextを呼び出したいとしましょうよ、のparamsの一つとしてnextを持っています。

私の質問は、同じモジュール内で異なるコールバック関数の間でreq,およびnextのパラメータを渡す最良の方法は何ですか。

方法1: パスreqresまたはnext私が合格しなければならない。この場合のように、チェーン内のすべての機能に周りに必要に応じて

は、私はそれを行うための3種類の方法を考え出しますnext~よりも、function1より大きく、function1からfunction2よりも大きい。

私の意見では最良の方法ではなく、維持管理が難しく、おそらく同様にテストしてください。

方法2: ラップ必要なすべてのparamsを通過addでクロージャとfunction1function2

'add': (req, res, next) => { 
    users.function2(next); 
    //....rest of the code of the function add 
} 

そしてfunction2自体より:

'function2': (next) => {4 
    return() => { 
     //...now I have access to next here 
     // without a need to pass it to each and every 
     // function in the chain 
    } 
} 

は方法3:

この特定のケースでは、私はそれは次のようになりますのみ function2 nextを渡すクロージャとをラップする必要があります

必要なすべての関数/変数をres.localsに追加し、resオブジェクトのみを渡します。

Method 1と全く同じ問題がありますので、個人的にはMethod 2になりますが、コードが読みにくくなったり、他の問題が発生したり、テストされていないかどうかはわかりません生産もチームとの開発環境でもありません。


私は本当にあなたの人がどのように使用しているのか、どのようにあなたのプロジェクト/チームで再生されて聞いてみたいです。すべての設定、ベストプラクティス、ベストパターン?共有してください、私は本当に何が最善の方法であるか知りたいです。

多分もっと良い方法がありますか?

フィードバックは非常に高く評価されています。


実際の生活の例:function1 & function2と、おそらく多くのため

使用例...

は、それが必要以上に、我々は、外部APIからデータを取得し、アダプタを持っているとしましょうデータをデータベースに保存し、応答を返します。また、APIから返されるデータが5秒後に期限切れになるとします。クライアントが5秒以内に経路にヒットした場合、呼び出し間の時間が長い場合はAPIを呼び出す操作を繰り返すよりも、データベースからデータを取得します。

これはもちろん、function1function2より複雑です。アダプタとデータベースの両方からコールバック関数を多数必要とし、データベース、アダプタからデータを取得し、データベースにデータを保存し、最終的にデータベースからデータを削除するための関数を別途必要とする場合、少なくとも4つのコールバック関数既に。

答えて

0

ミックスエクスプレスとアプリロジックは良い考えではないと思います。 私のプロジェクトで次の方法を使用します。

// middlewares/auth.js 
// Example middleware 
exports.isAdmin = function (req, res, next) { 
    if (smth-admin-check) 
     next(); 
    else 
     next (new Error(403)); 
} 

// routes/index.js 
// Include only modules from /routes 
let user = require('./user'); 
let auth = require('../middlewares/auth'); 
... 
app.get('/user/:id(\\d+)', user.get); 
app.post('/user', auth.isAdmin, user.post); // only admin can add user 

// routes/user.js 
// Call model methods and render/send data to browser 
// Don't know about db 
let User = require('/models/user'); 
... 
exports.get = function(req, res, next) { 
    let id = req.params.id; 
    // I cache most data in memory to avoid callback-hell 
    // But in common case code like below 
    User.get(id, function(err, u) { 
     if (!u) 
      return next(new Error('Bad id')); 

     ... render page or send json ... 
    }); 
} 
... 
exports.post = function(req, res, next) { ... } 

// models/user.js 
// Encapsulate user logic 
// Don't use any express features 
let db = require('my-db'); 
... 
class User { 
    get(id, callback) { ... } 
    add(data, callback) { ... } // return Error or new user 
    ... 
} 
+0

ロジックとエクスプレスルーティングはどこにありますか? 'users.add'関数はルートの' callback'ですので、 'router.post( '/'、users.add);'は、アプリケーション固有のロジックを高速ルーティングから分離する正確な場所です。 また、あなたの答えは問題を解決しません、あなたの例は完全に 'function2'問題をスキップする単純な単純なバージョンです。 – matewilk

+0

'function1'と' function2'の目的の例を挙げることができますか? –

+0

ちょうど一番下に例を挙げてanserを更新しました。ありがとう – matewilk

関連する問題