我正在创建一个语法,将解析器编译为JavaScript解析器。
然后我想使用async/await来调用访问者或侦听器中的异步函数。
由于默认生成的代码在函数中不包括async,因此不允许等待。
这是如何实现的?
您不能真正使用async
定义监听器,因为监听器方法不能返回任何内容(或者说没有使用它们的返回值(,所以不会对返回的promise执行任何操作。
但是,在访问者中使用async
效果非常好。只需将您的visitFoo
方法定义为async
,然后随意使用await
即可。例如:
class Interpreter extends MyLangVisitor {
async visitSleep(sleepCtx) {
let p = new Promise(function (resolve) {
setTimeout(resolve, sleepCtx.amount.text)
});
await p;
}
async visitProgram(programCtx) {
for(let command of programCtx.commands) {
await this.visit(command);
}
}
}
这将很好地工作,因为this.visit(command)
只是返回this.visitSleep(command)
的结果(或任何其他适用的方法(,这将是一个承诺。所以你在等待visitSleep
的承诺,一切都很顺利。
请注意,当您的方法是async
时,您不应该使用默认的visitChildren
方法,因为这将访问所有子级,而不会使用await
。你可以很容易地定义自己的版本:
async visitChildren(ctx) {
for(let child of ctx.children) {
await this.visit(child);
}
}