Mongodb findOne - return value



我需要通过调用函数从集合"users"中获取用户的id并返回其值。

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

但此实现返回null。修复它的方法是什么?

根据您的示例,如果您不想使用promise,您可以简单地从调用者传递回调,并在得到结果时调用回调,因为对mongo的调用是异步的。

fetchId = (name, clb) => {
  User.findOne({name: name}, (err, user) => {
    clb(user._id);
  });
};
fetchId("John", id => console.log(id));

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

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

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

第三种方法是@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)

编辑

对于异步工作的对象上的任何方法(包括属性getter(,调用代码都需要知道并采取相应的行动。

这往往会在系统中向上扩展到依赖于调用方调用方的任何东西,等等。我们无法避免这种情况,而且没有语法修复(编译器看到的是语法(。这是物理学:需要更长时间的东西,只需要更长的时间。我们可以使用语法来部分隐藏复杂性,但我们被额外的复杂性所困扰。

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

在这种方法下,调用者只需要记住一件事:告诉未准备好的用户在使用它之前做好准备。下面的代码采用了异步/等待风格的语法,这是最现代的,最能隐藏但不能消除:-(-异步复杂性…

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 _id,而是将整个mongo对象放起来。除非这是一个巨大的内存占用,否则我们还不如把它挂在身边,这样我们就可以获得任何远程存储的属性。

以下是来电者的样子。。。

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' } ];

最新更新