1

我正在使用 mongoose-q(流行的 mongoose mongodb ORM for node.js 的 promise 包装器)。

然而,我觉得也许这些嵌套的承诺并不比回调好多少。

有没有更好的方法来做这些查询?

User.findById(toFollowId)
    .execQ()
    .then(function(user){
        if (!user) return res.send(404);

        user.followers.addToSet(me);
        me.following.addToSet(user);

        me.saveQ()
            .then(function(me){
                user.saveQ()
                    .then(function(user){
                        getFollowerStats([me, user], function(err, data){
                            if ( err ) return res.json(400, err);

                            res.json(data);
                        });
                }).fail(function(err){
                    res.json(400, err);
                });
            })
            .fail(function(err){
                res.json(400, err);
            });
    }).fail(function(err){
        next(err);
    });
4

1 回答 1

1

为什么要重现典型的回调金字塔?

我建议重写代码如下。只有一个错误处理程序(fail fn),检查它是否符合您的需要。请注意,您必须包含 q 库。

q = require('q');


User.findById(toFollowId)
    .execQ()
    .then(function(user){
        if (!user) return res.send(404);

        user.followers.addToSet(me);
        me.following.addToSet(user);

        return q.all([me.saveQ(), user.saveQ()]);
    })
    .spread(function(me, user){
        getFollowerStats([me, user], function(err, data){
            if ( err ) return res.json(400, err);

            res.json(data);
        });
    })
    .fail(function(err){
        next(err);
    });

关于传播的说明:

如果你有一个数组的承诺,你可以使用 spread 作为 then 的替代品。传播函数将值“传播”到履行处理程序的参数上。拒绝处理程序将在第一个失败迹象时被调用。也就是说,无论哪个接收到的承诺首先失败,都会被拒绝处理程序处理。

有关完整说明,请参阅文档 ( http://documentup.com/kriskowal/q/ )。

这是使用“then”的替代方法:

User.findById(toFollowId)
    .execQ()
    .then(function(user){
        if (!user) return res.send(404);

        user.followers.addToSet(me);
        me.following.addToSet(user);

        return q.all([me.saveQ(), user.saveQ()]);
    })
    .then(function(resolvedArray){
        var me = resolvedArray[0],
            user = resolvedArray[1];

        getFollowerStats([me, user], function(err, data){
            if ( err ) return res.json(400, err);

            res.json(data);
        });
    })
    .fail(function(err){
        next(err);
    });
于 2014-08-17T17:21:02.177 回答