2016-05-15 15 views
4

ich den Express Rahmen verwenden und ich habe folgend in einem meiner Route Dateien:NodeJS Rückruf - Zugang zu ‚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)); 
    } 
}); 
} 

ich in eines meiner Routen der obige Funktion bin mit:

Jetzt kann der Callback, den ich beim Aufruf des "scan" auf dynamodbDoc definiere, sehr nützlich sein, wenn er als separate Funktion definiert wird. Ich kann das für einige meiner anderen Routen auch wiederverwenden.

Aber wie kann ich noch Zugang zu den "res" innerhalb dieser neuen Funktion bekommen?

Ich denke, ich sollte "Schließung" verwenden, aber ich kann nicht scheinen, es genau richtig zu bekommen. Ich glaube, ich würde benötigt die Unterschrift der neuen Callback-Funktion beizubehalten 2 params zu erwarten, „err“ und „Daten“ gemäß der folgenden Seite:

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

Alle Ideen, wie dies getan werden kann?

+0

Ich denke, Sie können den Callback in seine eigene benannte Funktion einfügen, solange sie sich im gleichen Bereich befindet, von dem 'dynamodbDoc.scan' aufgerufen wird. Hier hat Ihr Callback aufgrund des 'closure'-Features von JS Zugriff auf das gleiche' res'-Objekt wie 'dynamodbDoc.scan'. –

+0

Oh ja, das ist eine Option. Ich hätte das eigentlich in meiner Fragebeschreibung erwähnen sollen. Aber wenn ich das tue, dann wird diese Callback-Funktion nicht außerhalb der "allUserFromDynamoDB" -Funktion verfügbar sein.Angenommen, ich hatte eine andere Funktion (für eine andere Route) 'getSpecificUserFromDynamoDB' von wo ich es auch verwenden wollte. Hoffe, es ist klar, was ich sage. – vksinghh

+0

Problem ist, dass, wenn die Callback-Funktion außerhalb des Geltungsbereichs von 'allUsersFromDynamoDb' definiert ist, es keinen Zugriff auf' res' oder req' Objekte hat. Sie können einen Workaround finden, den ich denke (abhängig von der spezifischen Verwendung). –

Antwort

2

Sie diese Funktion als Middleware der einzelnen Routen können Sie http://expressjs.com/en/guide/using-middleware.html wollen

Die neue Route mit der Middleware:

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

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

Die Middleware (middlewares.js), wo Sie Ihre Daten req passieren, so dass Sie verwenden Sie diese Daten überall Sie req haben:

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(); 
     } 
    }); 
}; 

Und schließlich die Steuerung (controllers.js):

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

Danke für die Antwort Michelem! Was ich wirklich zu tun hoffte, war, den Großteil des Codes für "function (err, data)" wiederzuverwenden, so dass ich ihn für andere Routen, die ich habe, nicht wiederholen muss. Ich habe etwas basierend auf Ihrem Vorschlag gemacht, eine Middleware zu verwenden, die die Dinge etwas sauberer macht. Ich poste, was ich hier gemacht habe, als eine andere Antwort, da der Platz in einem Kommentar begrenzt ist. – vksinghh

1

Basierend auf MicheleM Antwort hier habe ich versucht, etwas, was die Dinge ein wenig sauberer und Code mehr wiederverwendbar macht:

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(); 
}); 
} 

Jetzt erkläre ich eine andere Funktion:

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)); 
} 
}; 

Und schließlich das:

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

Alles, was ich in der ursprünglichen tun müssen "-Funktion (err, Daten)" Rückruf immer gesetzt 2 Werte:

req.err = err 
req.data = data 

Und nennen next(). Und processUserResults kann in ähnlicher Weise für andere Routen verwendet werden.

Noch neugierig, ob es andere effiziente Lösungen gibt.

Verwandte Themen