我在试着了解这个行业的工具。
取这个代码:
function myFunction(a) // line 1
{ // line 2
someFunction(a); // line 3
someOtherFunction(a); // line 4
} // line 5
在这里,如果我的调试器在第3行暂停,如果我按下Step over按钮,会发生的是someFunction
运行,然后当它返回时,调试器在第4行暂停。这类似于在第4行设置断点并点击run,但它并不完全相同。这个someFunction的实现显示了差异:
function someFunction(b)
{
if (b > 0)
{
myFunction(b - 1);
}
}
在这种情况下,在第4行设置断点将在递归调用时中断,而单步执行第3行则不会。
现在让我们看一下带有一个blog语句的代码:
async function myAsyncFunction(a) // line 1
{ // line 2
await someAsyncFunction(a); // line 3
someOtherFunction(a); // line 4
} // line 5
我又一次让调试器暂停在第3行。我不清楚如果我按下“step over”会发生什么。这是不是又一次像在第4行设置断点一样?或者浏览器在这种情况下强制调用同步执行?或者发生了其他事情?
在我看来,这两种情况都不是完全直观的。从someAsyncFunction的实现中可以清楚地看到,可能会发生的一件更奇怪的事情:
function someAsyncFunction(a)
{
return new Promise(resolve => setTimeout(resolve, 60000));
}
这样一来,网站将在一分钟内完全可供用户交互,然后突然再次被调试器暂停,这不是我通常期望的按下step over的行为!
另一方面,如果强制同步执行函数,同样的实现会导致更大的问题:它会导致浏览器在一分钟内完全没有响应。所以也许我只是错过了整个情况的一些东西?
所以我的问题是:当我在await
语句处暂停时按下step over到底会发生什么?
我最感兴趣的是大型浏览器引擎(Firefox/Gecko,Chrome/Blink,Safari/Webkit)。了解Node的功能可能也很有趣,尽管它们的考虑因素可能完全不同(在没有浏览器的情况下,并不是我上面所有的逻辑都有意义)。总的来说,如果在这一点上有共识的话,这很有趣。但是我没有想到的其他引擎或环境可能也很有趣。
1条答案
按热度按时间wribegjk1#
这是不是又像在第4行设置断点一样?
是的,虽然(至少使用Chromium devtools和V8)与您在问题re
myFunction
中提到的区别。async
/await
的过时环境中编译的,并且您正在通过源Map查看源代码,则调试器可能无法在这里完成与实际async
/await
代码一样好的工作。或者在这种情况下,浏览器会强制调用同步执行吗?
它不能,调试器可以稍微弯曲JavaScript的规则,但不能强制异步进程同步。
有了这个,网站将成为用户完全可交互的一分钟,然后突然暂停调试器再次。
是的。如果您尝试它,就会发生这种情况,因为如果您跳过
await
,您将跳过处理结算的代码(实现或拒绝)的promiseawait
正在等待。因此,在promise解决之前,代码运行而不进行任何特殊处理(包括用户交互)是完全合理的。如果你想一想,在这种情况下,事情会一直沿着运行,直到事件发生,然后调试器停止事情。