2016-05-15 12 views
4

私はExpressのフレームワークを使用していると私は私のルートファイルのいずれかで、次のしている:私は私のルートの1つで上記の関数を使用していますNodeJSコールバック - へのアクセス「RES」

var allUsersFromDynamoDb = function (req, res) { 
var dynamodbDoc = new AWS.DynamoDB.DocumentClient(); 
var params = { 
    TableName: "users", 
    ProjectionExpression: "username,loc,age" 
}; 

dynamodbDoc.scan(params, function (err, data) { 
    if (err) { 
     console.error("Unable to query. Error:", JSON.stringify(err)); 
     res.statusCode = 500; 
     res.send("Internal Server Error"); 
    } else { 
     console.log("DynamoDB Query succeeded."); 
     res.end(JSON.stringify(data.Items)); 
    } 
}); 
} 

router.get('/users', allUsersFromDynamoDb); 

dynamodbDocで "スキャン"を呼び出す際に定義しているコールバックは、別の関数として定義するとかなり便利です。私は他のルートのいくつかにもそれを再利用することができます。

しかし、私はこの新しい機能の中でどうして "res"にアクセスできますか?

私は "閉鎖"を使用するべきだと思うが、私はそれを正確に得ることはできない。

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#scan-property

これを行う方法上の任意のアイデアを:私は、次のページのとおり、私は2つのparamsを期待する新しいコールバック関数のシグネチャを維持する必要があると思い、「ERR」と「データ」?

あなたが望むすべてのルートのミドルウェアとしてその機能を使用することができます
+0

'dynamodbDoc.scan'が呼び出されているスコープと同じスコープ内にある限り、コールバックを独自の名前付き関数に置くことができると思います。ここでは、JSの 'closure'機能のため、あなたのコールバックは' dynamodbDoc.scan'と同じ 'res'オブジェクトにアクセスします。 –

+0

ああ、それはオプションです。私は実際に私の質問の記述でそれを言及すべきだった。しかし、それを行うと、そのコールバック関数は 'allUserFromDynamoDB'関数の外部で利用できなくなります。私は別の機能(別のルートのために) 'getSpecificUserFromDynamoDB'を使用したいところから持っていたとしましょう。私が言っていることがはっきりしていることを願っています。 – vksinghh

+0

問題は、コールバック関数が 'allUsersFromDynamoDb'のスコープ外で定義されている場合、' res'またはreq'オブジェクトにアクセスすることができないということです。特定の用途に応じて、私が考える回避策を見つけることができます。 –

答えて

2

http://expressjs.com/en/guide/using-middleware.html

ミドルウェアを使用して新しいルート:

var middlewares = require('./middlewares'), 
    controllers = require('./controllers'); 

router.get('/users', middlewares.allUsersFromDynamoDb, controllers.theRouteController); 

あなたはreqそうすることができますにデータを渡すミドルウェア(middlewares.js)どこにいてもそのデータを使用してくださいreq

exports.allUsersFromDynamoDb = function (req, res, next) { 
    var dynamodbDoc = new AWS.DynamoDB.DocumentClient(); 
    var params = { 
     TableName: "users", 
     ProjectionExpression: "username,loc,age" 
    }; 

    dynamodbDoc.scan(params, function (err, data) { 
     if (err) { 
      console.error("Unable to query. Error:", JSON.stringify(err)); 
      next("Internal Server Error"); 
     } else { 
      console.log("DynamoDB Query succeeded."); 
      req.dataScan = JSON.stringify(data.Items); 
      next(); 
     } 
    }); 
}; 

最後に、コントローラ(controllers.js):ここMichelemの答えに基づいて

exports.theRouteController = function (req, res) { 
    // Here is the dataScan you defined in the middleware 
    res.jsonp(req.dataScan); 
}; 
+0

答えMichelemありがとう!私が本当に望んでいたことは、コードの大部分を「機能(エラー、データ)」に再利用することでした。したがって、私が持っている他のルートでも繰り返す必要はありません。私は物事を少しきれいにしたミドルウェアを使用するというあなたの提案に基づいて何かをしました。コメントのスペースが限られているので、別の答えとして私がここで行ったことを投稿します。 – vksinghh

1

は、私は物事ビットクリーナーとコードをより再利用可能になり、何かを試してみました:

var allUsersFromDynamoDb = function (req, res, next) { 
var dynamodbDoc = new AWS.DynamoDB.DocumentClient(); 
var params = { 
    TableName: "users", 
    ProjectionExpression: "username,loc,age" 
}; 

dynamodbDoc.scan(params, function (err, data) { 
    req.err = err; 
    req.data = data; 
    next(); 
}); 
} 

は今、私は別の関数を宣言します。

var processUserResults = function (req, res, next) { 
if (req.err) { 
    console.error("Unable to query. Error:", JSON.stringify(req.err)); 
    res.statusCode = 500; 
    res.send("Internal Server Error"); 
} else { 
    console.log("DynamoDB Query succeeded."); 
    res.end(JSON.stringify(req.data.Items)); 
} 
}; 

そして、最後に、これは:

router.get('/users', [allUsersFromDynamoDb, processUserResults]); 

私はオリジナルでやらなければならないこと「機能が(ERR、データ)」コールバックは、常に2つの値に設定されています

req.err = err 
req.data = data 

をし、次の呼び出し()。 processUserResultsは他のルートでも同様に使用できます。

その他の効率的な解決方法があるかどうかはまだ不明です。