NodeJS回调 - 访问' res'

时间:2016-05-15 07:21:44

标签: node.js callback closures

我正在使用Express框架,我在其中一个路径文件中有以下内容:

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

现在我在调用" scan"时定义的回调。如果定义为单独的函数,则dynamodbDoc非常有用。我也可以为我的其他一些路线重复使用它。

但是我怎样仍然可以访问" res"在这个新功能里面?

我想我应该使用"关闭"但我似乎无法让它完全正确。我想我需要保持新回调函数的签名,以期望2个参数,"错误"和"数据"按照以下页面:

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

关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:2)

您可以将该功能用作您想要的每条路线的中间件http://expressjs.com/en/guide/using-middleware.html

带有中间件的新路线:

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

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

将数据传递到middlewares.js的中间件(req),以便您可以在任何地方使用该数据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):

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

答案 1 :(得分:1)

基于Michelem的答案,我尝试了一些让事情变得更清晰,编码更可重复使用的东西:

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

所有我需要做的原始"功能(错误,数据)"回调总是设置2个值:

req.err = err
req.data = data

然后拨打下一个()。 processUserResults可以类似地用于其他路由。

仍然很想知道是否还有其他有效的解决方案。