在 类 中处理回调
Handling Callbacks in Classes
我正在构建 classes 来查找和快速操作 mongodb 文档。这是 UserCursor class。 (不是说 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;
}
}
当运行时,控制台returns
2
1
我认为您遇到了问题:构造函数中的 mongo 回调在 _id
操作之后开始。我怎么能做到这一点,因为每次使用 class 时都会激活构造函数?
我不完全清楚你到底想发生什么以及你如何使用这个 class 但我假设你想实例化它然后能够立即获得 _id 。如果不是这种情况,您仍然可以从我的回答中获得一些有用的信息。欢迎提供更多细节,我会更新。
所以 mongodb 操作是异步的,如果你这样做
const cursor = new UserCursor(...)
console.log(cursor._id)
(我假设你想要这个),首先这个线程中的所有操作将 运行,包括对 get _id()
的调用,然后是回调代码。此类异步事物的问题在于,现在要使用此 _id,您还必须使所有代码都异步。
因此,您将需要存储一个从 mongodb 以 _id
解析的 Promise,并创建一个方法 getId
return 如下所示:
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
你也可以像现在这样留下一个 getter,这将 return 一个承诺,但我发现它的可读性不如 getId()
:
cursor._id.then(_id => { ... })
const _id = await cursor._id
我正在构建 classes 来查找和快速操作 mongodb 文档。这是 UserCursor class。 (不是说 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;
}
}
当运行时,控制台returns
2
1
我认为您遇到了问题:构造函数中的 mongo 回调在 _id
操作之后开始。我怎么能做到这一点,因为每次使用 class 时都会激活构造函数?
我不完全清楚你到底想发生什么以及你如何使用这个 class 但我假设你想实例化它然后能够立即获得 _id 。如果不是这种情况,您仍然可以从我的回答中获得一些有用的信息。欢迎提供更多细节,我会更新。
所以 mongodb 操作是异步的,如果你这样做
const cursor = new UserCursor(...)
console.log(cursor._id)
(我假设你想要这个),首先这个线程中的所有操作将 运行,包括对 get _id()
的调用,然后是回调代码。此类异步事物的问题在于,现在要使用此 _id,您还必须使所有代码都异步。
因此,您将需要存储一个从 mongodb 以 _id
解析的 Promise,并创建一个方法 getId
return 如下所示:
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
你也可以像现在这样留下一个 getter,这将 return 一个承诺,但我发现它的可读性不如 getId()
:
cursor._id.then(_id => { ... })
const _id = await cursor._id