How to use “q” module for refactoring mongoose code?

后端 未结 5 519
野趣味
野趣味 2020-12-31 04:30

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

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


        
5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-31 04:40

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

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

提交回复
热议问题