如何在不使用回调的情况下从Mongoose获取数据?

时间:2015-06-19 23:32:28

标签: node.js mongodb mongoose

最终,我的知识非常糟糕,就像我几个小时前开始的那样。但在我看来,这应该有效:

getAll: function(callback){
    User.find({}, function (err, data) {
        if (err) return console.error(err);
        return data;
    });
}

var users = api.getAll(); 
console.log(users); //undefined

但出于某种原因,我必须将其作为callBack传递,以使数据工作如下:

getAll: function(callback){
    User.find({}, function (err, kittens) {
        if (err) return console.error(err);
        callback(kittens);
    });
}
var users = api.getAll(function (data) {
    console.info(data); //does output data
});

我如何获得选项一,更容易阅读2工作?

1 个答案:

答案 0 :(得分:1)

不幸的是,你不能。当你执行一个函数时,你得到了从它返回的任何东西。如果您没有返回任何内容,则默认情况下会获得undefined

除了基于获取 user的可读性之外,您应该根据您在获得它之后要做的事情来获得它。大概你会有一些你想要对用户执行的动作,对吗?这就是Promise可以让你的代码看起来比回调更好的地方。

这里的代码是用Promise重写的

getAll: function(callback){
    return User.findAsync({});
}
api.getAll()
.then(console.log)
.catch(console.error); 

因为你想要做的只是"执行" console.log上的users {和console.error err findAsync如果发生这种情况,这正是上述代码的作用。

请注意,我使用user来自Bluebird' s promisification

但更现实的是,您有与api.getAll() .then(filterSome) .then(manipulateSome) .then(sendSomewhere) .catch(console.error);

一起做其他事情的功能
function filterSome(users){
    return users.reduce(function(p,e){
        if(…) p.push(e);
        return p;
},[]);  }

这些功能中的每一个都可能如下所示:

function manipulateSome(users){
    return new Promise.all(user.map(function(user){
        return new Promise(function(resolve){
            someAsyncFunction(user, function(err, result){
                user.someProp = result.manipulated;
                resolve(user);
}); }); }));}

它们甚至可以是异步函数,在这种情况下你将不得不使用更多的Promise:

getAll: async function(callback){
    return User.findAsync({});
}
try{
    var users = await api.getAll();
    console.log(users);
catch(e){
    console.error(e)
}

如果那仍然看起来很混乱,那么知道即将推出的ES7以上所有内容都会得到一个语法糖,你会做这样的事情:

Entry

您今天可以开始使用BabelJS

等转录程序