Node.js 在类中处理回调

Node.js 在类中处理回调,node.js,mongodb,typescript,mongodb-nodejs-driver,Node.js,Mongodb,Typescript,Mongodb Nodejs Driver,我正在构建类来查找和快速操作mongodb文档上的操作。这是UserCursor类。(不是说MongoDB的游标) 运行时,控制台返回 2 1. 我认为您遇到了问题:构造函数中的mongo回调在\u id运行后启动。既然每次使用该类时都会激活构造函数,那么我该如何管理它呢?我还不完全清楚您到底想要发生什么以及如何使用该类,但我假设您想要实例化它,然后能够立即获得_id。如果不是这样,你仍然可以从我的回答中得到一些有用的信息。请随时提供更多细节,我会更新它 所以mongodb操作是异步的,如果您

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

运行时,控制台返回

2
1.

我认为您遇到了问题:构造函数中的mongo回调在
\u id
运行后启动。既然每次使用该类时都会激活构造函数,那么我该如何管理它呢?

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

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

const cursor=new UserCursor(…)
console.log(游标。\u id)
(我假设您希望这样做),首先将运行此线程中的所有操作,包括调用
get\u id()
,然后将运行回调代码。这种异步方式的问题是,现在要使用这个id,您还必须使所有代码都是异步的

因此,您需要存储一个使用mongodb中的
\u id
解析的承诺,并创建一个方法
getId
,该方法返回此承诺如下:

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

如果现在在某个函数中执行此操作,则还必须使该函数
异步

您也可以像现在这样留下一个getter,它将返回一个承诺,但我发现它的可读性不如
getId()


如果需要异步初始化,则必须使用工厂。此外,您正在传递回调以返回承诺的所有方法,因此您应该使用该API
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()
cursor._id.then(_id => { ... })
const _id = await cursor._id