Mongodb findOne-返回值

时间:2018-11-13 18:10:09

标签: javascript node.js mongodb

我需要通过调用函数从集合“用户”中获取用户ID并返回其值。

fetchId = (name) => {
        User.findOne({name: name}, (err, user) => {
            return user._id;
        });
    };

但是此实现返回null。解决该问题的方法是什么?

2 个答案:

答案 0 :(得分:3)

在您的示例之后,如果您不想使用Promise,您可以简单地传递来自调用方的回调,并在得到结果后调用该回调,因为对mongo的调用是异步的。

fetchId = (name, clb) => {
  User.findOne({name: name}, (err, user) => {
    clb(user._id);
  });
};

fetchId("John", id => console.log(id));

否则,您可以使用基于承诺的机制,省略第一个回调,并将承诺返回给调用方。

fetchId = name => {
  return User.findOne({name: name}).then(user => user.id);
}; 


fetchId("John")
 .then(id => console.log(id));

答案 1 :(得分:0)

第三种方法是@Karim的(非常好)答案中建议2的变体。如果OP希望对它进行编码,就好像从异步代码中分配了结果,则可以将fetchId声明为async并将其结果await声明为一个改进...

fetchId = async (name) => {
    return User.findOne({name: name}).then(user => user.id);
};

let someId = await fetchId("John");
console.log(id)

修改

对于对象上的任何方法-包括属性获取器-都是异步工作的,调用代码需要意识到并采取相应的行动。

这倾向于在您的系统中扩展到依赖于呼叫者的呼叫者的任何事物,依此类推。我们无法避免这种情况,并且没有语法修复(语法是编译器看到的)。这是物理学:需要更长的时间,只是需要更长的时间。我们可以使用语法来部分掩盖复杂性,但是我们被额外的复杂性所困。

将其应用于您的问题,假设我们有一个代表用户的对象,该对象由mongo远程存储。最简单的方法是在异步获取(findOne)操作完成之前将内存中的用户对象视为未就绪。

在这种方法下,调用者只需记住一件事:告诉未准备就绪的用户在使用前做好准备。下面的代码采用了async / await风格的语法,这是最现代的,并且可以最大程度地隐藏-但不能消除:-(-异步复杂性...

class MyMongoUser {
    // after new, this in-memory user is not ready
    constructor(name) {
        this.name = name;
        this.mongoUser = null;  // optional, see how we're not ready?
    }

    // callers must understand: before using, tell it to get ready!
    async getReady() {
        this.mongoUser = await myAsyncMongoGetter();
        // if there are other properties that are computed asynchronously, do those here, too
    }

    async myAsyncMongoGetter() {
        // call mongo
        const self = this;
        return User.findOne({name: self.name}).then(result => {
            // grab the whole remote object. see below
            self.mongoUser = result;
        });
    }

    // the remaining methods can be synchronous, but callers must
    // understand that these won't work until the object is ready
    mongoId() {
        return (this.mongoUser)? this.mongoUser._id : null;
    }

    posts() {
        return [ { creator_id: this.mongoId() } ];
    }
}

请注意,我们丢弃了整个mongo对象,而不仅仅是从用户那里抢走mongo _id。除非这是一个巨大的内存消耗,否则我们最好将其挂起,以便获得任何远程存储的属性。

这里是呼叫者的样子...

let joe = new MyMongoUser('joe');
console.log(joe.posts()) // isn't ready, so this logs [ { creator_id: null } ];
await joe.getReady();
console.log(joe.posts()) // logs [ { creator_id: 'the mongo id' } ];