如何使用" Q"模块重构猫鼬code? [英] How to use "q" module for refactoring mongoose code?

查看:122
本文介绍了如何使用" Q"模块重构猫鼬code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用猫鼬的一些数据插入到MongoDB中。在code如下:

I'm using mongoose to insert some data into mongodb. The code looks like:

var mongoose = require('mongoose');
mongoose.connect('mongo://localhost/test');
var conn = mongoose.connection;

// insert users
conn.collection('users').insert([{/*user1*/},{/*user2*/}], function(err, docs) {
    var user1 = docs[0], user2 = docs[1];

    // insert channels
    conn.collection('channels').insert([{userId:user1._id},{userId:user2._id}], function(err, docs) {
        var channel1 = docs[0], channel2 = docs[1];

        // insert articles
        conn.collection('articles').insert([{userId:user1._id,channelId:channel1._id},{}], function(err, docs) {
            var article1 = docs[0], article2 = docs[1];

        }
    });
};

您可以看到有很多的嵌套回调那里,所以我尝试使用 q 来重构它。

You can see there are a lot of nested callbacks there, so I'm trying to use q to refactor it.

我希望code将看起来像:

I hope the code will look like:

Q.fcall(step1)
.then(step2)
.then(step3)
.then(step4)
.then(function (value4) {
    // Do something with value4
}, function (error) {
    // Handle any error from step1 through step4
})
.end();

但我不知道该怎么办了。

But I don't know how to do it.

推荐答案

您需要使用 Q.nfcall ,记录的in~~V自述和维基。猫鼬的所有方法都是节点式。我还将使用 .S $ P $垫,而不是手动解构。然后

You'll want to use Q.nfcall, documented in the README and the Wiki. All Mongoose methods are Node-style. I'll also use .spread instead of manually destructuring .then.

var mongoose = require('mongoose');
mongoose.connect('mongo://localhost/test');
var conn = mongoose.connection;

var users = conn.collection('users');
var channels = conn.collection('channels');
var articles = conn.collection('articles');

function getInsertedArticles() {
    return Q.nfcall(users.insert.bind(users), [{/*user1*/},{/*user2*/}]).spread(function (user1, user2) {
        return Q.nfcall(channels.insert.bind(channels), [{userId:user1._id},{userId:user2._id}]).spread(function (channel1, channel2) {
            return Q.nfcall(articles.insert.bind(articles), [{userId:user1._id,channelId:channel1._id},{}]);
        });
    })
}

getInsertedArticles()
    .spread(function (article1, article2) {
        // you only get here if all three of the above steps succeeded
    })
    .fail(function (error) {
        // you get here if any of the above three steps failed
    }
);

在实践中,你很少会需要使用 .S $ P $垫,因为你通常会插入一个数组,你不知道的大小。在这种情况下,code能看起来更这样(我在这里也说明 Q.nbind )。

In practice, you will rarely want to use .spread, since you usually are inserting an array that you don't know the size of. In that case the code can look more like this (here I also illustrate Q.nbind).

要与原来的比较是不太公平的,因为你原来的没有错误处理。原来的修正节点式版本会像这样:

To compare with the original one is not quite fair, because your original has no error handling. A corrected Node-style version of the original would be like so:

var mongoose = require('mongoose');
mongoose.connect('mongo://localhost/test');
var conn = mongoose.connection;

function getInsertedArticles(cb) {
    // insert users
    conn.collection('users').insert([{/*user1*/},{/*user2*/}], function(err, docs) {
        if (err) {
            cb(err);
            return;
        }

        var user1 = docs[0], user2 = docs[1];

        // insert channels
        conn.collection('channels').insert([{userId:user1._id},{userId:user2._id}], function(err, docs) {
            if (err) {
                cb(err);
                return;
            }

            var channel1 = docs[0], channel2 = docs[1];

            // insert articles
            conn.collection('articles').insert([{userId:user1._id,channelId:channel1._id},{}], function(err, docs) {
                if (err) {
                    cb(err);
                    return;
                }

                var article1 = docs[0], article2 = docs[1];

                cb(null, [article1, article2]);
            }
        });
    };
}

getInsertedArticles(function (err, articles) {
    if (err) {
        // you get here if any of the three steps failed.
        // `articles` is `undefined`.
    } else {
        // you get here if all three succeeded.
        // `err` is null.
    }
});

这篇关于如何使用" Q"模块重构猫鼬code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆