在等待异步方法完成时如何正确发布响应?

时间:2015-08-05 00:52:42

标签: javascript node.js

希望这个很简单,但对我来说有点令人费解。

这是模块中的设置。参见,特别是由****标记的评论:

exports.saveWall = function (req, res) {
    var status;

    mongoClient.connect(connectionString, function (err, db) {
        if (err) { return console.dir(err); }

        db.collection(pictureWallsCollectionName).insert(
            { _id: req.body.wallId, pictures: req.body.pictures }, 
            function (err, res) {   
                db.close();
                if (err) {
                    status = 500;
                    console.dir(err);
                }
                else {
                    status = 200;
                    //*****can't do this here, because res is out of scope!
                    res.status(status).send(http.STATUS_CODES[status])
                    console.log('Inserted into the ' + pictureWallsCollectionName + ' collection');                     
                }
            });      
    });

    //*****can't do this yet because the above isn't done.
    res.status(status).send(http.STATUS_CODES[status])
}

我基本上想在回调中调用行res.status(status).send(http.STATUS_CODES[status]),但我不能,因为此时res.status为空。

我想做的就是回复POST。但是我把头撞在墙上看似简单的东西。救命啊!

2 个答案:

答案 0 :(得分:1)

啊...

事实证明我的问题是“res”在这里定义了:

exports.saveWall = function (req, res) {

......在这里:

db.collection(pictureWallsCollectionName).insert(..., 
        function (err, res) {

...所以事实证明我可以一直调用“res”,我只是试图调用错误的“res”,因为它被重新定义了。

旁注,f ***你,javascript!

答案 1 :(得分:1)

即使您解决了范围问题(这很棒),嵌套回调也会很快变得棘手(如您所见)。解决这个问题的一个好方法是使用promises。承诺的两个主要包是QBluebird(Bluebird是我的最爱)。

您还可以使用已经承诺过mongo呼叫的软件包,例如promised-mongo

一旦完成所有设置,只需将.then链接到后续步骤,然后在解决承诺时发送您的回复。

有关具体示例,请查看此answer,看看是否有帮助。