Chrome 调试器 - 从模板调用的异步函数中的参数

Chrome debugger - parameters in async functions called from template

我的模板在 angular 我使用以下组件:

 <building-selection 
     (done)="sendToBackend($event)"
     >
 </building-selection>

此组件向用户显示带有复选框的建筑物图像,当他完成检查时会发出带有所选建筑物数组的事件

在以下功能的打字稿代码中:

public async sendToBackend(buildings) 
{
    console.log({buildings}); 
    debugger; // I see buildings "debugger variable preview"
    ... 
}

但是如果我注释掉 console.log 然后在“调试器变量 预览”我看到消息(如果我们有非异步功能则不会出现这种现象):

ReferenceError: buildings is not defined at eval (eval at (http://project.localhost:3003/main.bundle.js:53596:17), :1:1) at ClientProjectEditorComponent.

... invokeTask (http://project.localhost:3003/polyfills.bundle.js:14037:14)↵ at HTMLUnknownElement.globalZoneAwareCallback (http://project.localhost:3003/polyfills.bundle.js:14063:17)" proto : Error

问题:为什么注释掉console语句后debugger关键字的作用不同?

问题是 async 函数将被转换为生成器函数,每次您 await 时都会迭代。例如:

public async sendToBackend(buildings) 
{
    await sleep();
    debugger; 
    await sleep();
}
// Generated js for target es2015

sendToBackend(buildings) {
    return __awaiter(this, void 0, void 0, function* () {
        yield sleep();
        debugger; 
        yield sleep();
    });
}

如您所见,实际函数的代码将以匿名函数形式结束,该函数将传递给 __awaiter 辅助函数。参数列表仍然存在于原始函数中,匿名函数可以访问参数,但是如果匿名函数没有通过在它的主体中引用它们来捕获参数,那么调试器将无法检查它们。当您添加 console.log 时,匿名函数引用参数,因此它将被捕获并因此可用于手表中的检查。

上面的代码是为 es2015 编译的,es5 的讨论类似,但是生成的代码更难理解,因为还必须模拟生成器。