0

我正在构建类来查找和快速操作 mongodb 文档上的操作。这是 UserCursor 类。(不是在谈论 MongoDB 的游标)

exports { UserCursor };
class UserCursor {

    private __id: object;

    constructor(query: { _id?: object, otherId?: number }) {
        let { _id, otherId } = query; // Shortens the vars' name
        if (!_id && !otherId) return; // Checks if 1 identifier is provided

        if (_id) { // If a _id is provided
            Users.findOne({ _id }, (err, user) => {
                this.__id = user._id;
            });
        } else if (otherId) { // If a otherId is provided
            Users.findOne({ otherId }, (err, user) => {
                console.log(1); // Debug, you'll see later
                this.__id = user._id;
            });
        }
    }


    // Returns this.__id (which should have been initialized in the constructor)
    get _id() {
        console.log(2)
        return this.__id;
    }

}

运行时,控制台返回

2
1

我认为您遇到了问题:构造函数中的 mongo 回调在_id操作后启动。由于每次使用该类时都会激活构造函数,我该如何管理它?

4

1 回答 1

1

我并不完全清楚你到底想要发生什么以及如何使用这个类,但我假设你想实例化它,然后能够立即获得 _id。如果不是这样,您仍然可以从我的回答中获得一些有用的信息。请随时提供更多详细信息,我会更新它。

所以mongodb操作是异步的,如果你这样做

const cursor = new UserCursor(...)
console.log(cursor._id)

(我假设你想要这个),首先这个线程中的所有操作都会运行,包括对 的调用get _id(),然后是回调代码。这种异步事物的问题在于,现在要使用这个 _id,您还必须使所有代码都异步。

因此,您需要存储一个使用_idmongodb 解析的 Promise,并创建一个getId返回此 Promise 的方法,如下所示:

private __id: Promise<object>

constructor(...) {
  // ...
  if(_id) {
    this.__id = new Promise((resolve, reject) => {
       Users.findOne({ _id }, (err, user) => {
          if(err) return reject(err)
          resolve(user._id)
       });
    })
  } else {
    // Same here
  }
}

public getId() {
   return this.__id;
}

然后使用它:

const cursor = new UserCursor(...)
cursor.getId().then(_id => {
  // Do smth with _id
})

或者

async function doStuff() {
  const cursor = new UserCursor()
  const _id = await cursor.getId()
}
doStuff()

如果您现在在某个函数中执行此操作,则还必须创建该函数async

您也可以像现在一样留下一个吸气剂,这将返回一个承诺,但我发现它的可读性低于getId()

cursor._id.then(_id => { ... })
const _id = await cursor._id
于 2020-08-16T04:07:25.793 回答