bluebird 多层嵌套该如何优化。
发布于 8 年前 作者 youngdeer 7256 次浏览 来自 问答
var mongodb = require('./db');
var Promise = require("bluebird");
Promise.promisifyAll(mongodb);
Account.prototype.save = function save(callback){
    var account = {
        user: this.name,
        number: this.number,
        type: this.type,
        time: this.time,
    }

    mongodb.openAsync()
        .then(function(db){
            Promise.promisifyAll(db);
            db.collectionAsync('accounts')
                .then(function(collection){
                    collection.ensureIndex('user');
                    Promise.promisifyAll(collection);
                    collection.insertAsync(account,{safe:true})
                        .then(function(account){
                            mongodb.close();
                            return callback(null,account);
                        })
                        .catch(function(err){
                            mongodb.close();
                            return callback(err,null);
                        });
                })
                .catch(function(err){
                    mongodb.close();
                    return callback(err);
                });
        })
        .catch(function(err){
            return callback(err);
        });
}

这种情况下,要怎么优化一下。求大神指导!!

10 回复

https://cnodejs.org/topic/560dbc826a1ed28204a1e7de

优化方案

mongoose上的static和method上扩展,别暴漏太多细节在控制层 面向promise,保证每个操作都是一个函数,让流程可以组装,不要忘了最初then的初衷

function find_user() {
    return User.findByIdAsync(user_id);
}

function find_user2() {
    return User.findByIdAsync(user_id);
}

function error(ex){
  console.log(ex);
}

TeamPartner.updateByXXAsync(a,b,c).then(find_user).then(find_user2).catch(error)

@i5ting

function1(){
	return xxx.f1Async();
}
function2(data){
	return yyy.f2Async();
}
xxxAsync().then(funtion1).then(function2)

这样的形式function2的参数data是否能由function1返回得到。我这边写了却获取到了undefined

@youngdeer xxx.f1Async()的结果就是,function2的参数

@i5ting

function getCollection(db){
    return db.collectionAsync('accounts');
}

mongodb.openAsync()
        .then(function(db){
            Promise.promisifyAll(db);
            getCollection(db);
        })
        .then(function(collection){
            console.log(collection);
		}

我的代码是这样子的,到获取collection的时候,就获取到undefined了,能帮忙指导一下么。

@i5ting

mongodb.openAsync()
        .then(function(db){
            Promise.promisifyAll(db);
            return db.collectionAsync('accounts');
        })
        .then(function(collection){
            console.log(collection);
        }

这样子就是没有问题的,有点疑惑。。。。。

@i5ting

var getCollection = function(db){
    Promise.promisifyAll(db);
    return db.collectionAsync('accounts');
}

mongodb.openAsync()
        .then(getCollection)
        .then(function(collection){
            collection.ensureIndex('user');
            Promise.promisifyAll(collection);
            return collection.insertAsync(account,{safe:true});
        })

解决了,突然想起来then里面一定是一个promise的值,就是有一点还有些不太好用,如果function2里还要用到返回值以外的参数,感觉只能放全局变量,不然提取不到外边去,就比如我代码里的

.then(function(collection){
            collection.ensureIndex('user');
            Promise.promisifyAll(collection);
            return collection.insertAsync(account,{safe:true});
        })

这里的account的值,若要把这个then里的promise值提取到外边去,只能定义全局变量么。

@i5ting

var mongodb = require('./db');
var Promise = require("bluebird");
Promise.promisifyAll(mongodb);

Account.prototype.save = function save(callback){
    var account = {
        user: this.name,
        number: this.number,
        type: this.type,
        time: this.time,
    }

    var getCollection = function(db){
        Promise.promisifyAll(db);
        return db.collectionAsync('accounts');
    }

    var collectionInsert = function(collection){
        collection.ensureIndex('user');
        Promise.promisifyAll(collection);
        return collection.insertAsync(account,{safe:true});
    }

    var saveSuccess = function(){
        mongodb.close();
        return callback();
    }

    var saveFail = function(err){
        mongodb.close();
        return callback(err);
    }

    mongodb.openAsync()
        .then(getCollection)
        .then(collectionInsert)
        .then(saveSuccess)
        .catch(saveFail);
}

在您的指导下,代码最终优化成了这样,请问是否还可以有改进的地方=。=!!!

看着这么多 Promise.promisifyAll,感觉好辛苦。

我看 bluebird 的文档,应该是可以在 prototype 的层面上进行一次性 Promise.promisifyAll 的。

var App = function () {
	this.name = '';
	this.sex = '男';
	
	this.init();
};

App.prototype = {
	init: function () { //程序入口
		console.log('初始化');
		this.writeName();
	},
	writeName: function () { //输出姓名
		console.log(this.name);
		this.writeSex();
	},
	writeSex: function () { //输出性别
		console.log(this.sex);
	}
};
new App(); //启动程序


可以尝试下我这种写法试试,能解决层层嵌套的问题,模块化开发
回到顶部