【发布时间】:2020-10-31 03:12:17
【问题描述】:
我正在编写一个模块,旨在在将查询调用到数据库之前准备查询。 vanilla javascript 中的代码运行良好,但是当我尝试用 Typescript 编写它时,出现错误:Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member
我的 Javascript 代码:
class QueryBuilder {
constructor(query) {
this.query = query;
}
sort(keyOrList, direction) {
this.query = this.query.sort(keyOrList);
return this;
}
skip(value) {
this.query = this.query.skip(value);
return this;
}
limit(value) {
this.query = this.query.limit(value);
return this;
}
then(cb) {
cb(this.query.toArray());
}
}
打字稿中的代码:
class QueryBuilder {
public query: Cursor;
constructor(query: Cursor) {
this.query = query;
}
public sort(keyOrList: string | object[] | object, direction: any) {
this.query = this.query.sort(keyOrList);
return this;
}
public skip(value: number) {
this.query = this.query.skip(value);
return this;
}
public limit(value: number) {
this.query = this.query.limit(value);
return this;
}
public then(cb: Function) {
cb(this.query.toArray());
}
}
我如何调用这些方法:
const query = await new QueryBuilder(Model.find())
.limit(5)
.skip(5)
希望有人可以帮助我。提前致谢。
*更新:
我从buitin Promise 扩展了QueryBuilder 类,然后用QueryBuilder.prototype.then 覆盖了then 方法。代码现在是可执行的,但我并没有真正理解构造函数中的super(executor)。它需要executor(resolve: (value?: T | PromiseLike<T> | undefined) => void, reject: (reason?: any) => void): void,所以我只是简单地创建了一个哑执行器。对代码有什么影响?
class QueryBuilder<T> extends Promise<T> {
public query: Cursor;
constructor(query: Cursor) {
super((resolve: any, reject: any) => {
resolve("ok");
});
this.query = query;
}
public sort(keyOrList: string | object[] | object, direction?: any) {
this.query = this.query.sort(keyOrList);
return this;
}
public skip(value: number) {
this.query = this.query.skip(value);
return this;
}
public limit(value: number) {
this.query = this.query.limit(value);
return this;
}
}
QueryBuilder.prototype.then = function (resolve: any, reject: any) {
return resolve(this.query.toArray());
};
【问题讨论】:
-
我认为不需要在
query初始化语句中添加await。 QueryBuilder 类初始化操作没有返回任何promise,因此报错。 -
即使在从查询实例化语句中删除
await之后,您仍然应该能够chain操作。 -
@DhruvShah
this.query.toArray()可能会返回一个 Promise,因此,您必须await它的结果。链接本身也不是问题。 OP 代码的重点是实际执行异步查询并在与await一起使用时等待其结果。 -
看在上帝的份上,如果你的类不符合 Promises/A+ 规范(它不符合),请不要给你的类一个
.then方法。你不想引爆another flame war。 -
@vmtran 不,我所说的完全不是针对 Typescript 的。是的,您可以实现
.then函数,使其不符合 Promisea/A+ 但async仍然能够处理它,但这是一种可怕的做法。如果有人真的试图直接使用你的.then方法,他们最终会得到一个Zalgo。如果他们可以理解地试图摆脱它,他们也会以错误告终。
标签: javascript node.js typescript async-await chaining