【Debug】 你所不知道的各种前端Debug技巧系列 Sources - Step-by-Step Execution---第13天

利用断点暂停程式码后,就能控制程式码的执行来进行更进一步的Debug,笔者会在本篇文章介绍如何在Sources 面板中进行JavaScript Debugging。

概览
使用Sources 面板进行Debug 的流程大致上可分为以下四个步骤

重现问题-- 找出产生Bug 的流程,例如只要照着A、B 的顺序点击按钮就会出现问题。
建立断点-- 确定Bug 的产生方式后,选择适当的断点来快速找到问题程式码的位置。
控制执行-- 暂停程式码后,利用跳跃、逐步执行等方式控制程式码的进行,观察执行流程是否符合预期。
检查状态-- 逐步执行过程中可以监看变数、Call stack 的状态,或是执行程式码来检查变数的值。
若还不熟悉断点的建立方式,可以参考Sources - Breakpoints,接下来的内容会包含控制执行以及检查变数。
阅读本文时建议搭配Demo页面Sources - Step-by-Step Execution,效果更佳。

执行控制

执行控制就像是程式码的播放器,有暂停、继续、跳至点击处等功能,在控制的过程中观察变数值的变化,借此找出程式码的问题。

当程式码暂停执行时可以在程式码的任意位置按下右键,选择Continue to Here快转到该处,略过没有兴趣的部分,当然也可以在该位置新增一个断点并按下继续,会有一样的效果。
在这里插入图片描述
有时会想用一帧一帧慢慢播放的方式来看清影片的每个细节,而逐步执行就相当于播放影片时的「下个影格」功能。

逐步执行(Step)

面板上方可以很多个箭头状图示,它们都叫做逐步执行,但在某些情况会有不同的行为。
在这里插入图片描述

Step over next function call

如果对即将执行的Function内部没有兴趣,Step over会跳至该Function后方。

以下方程式码为例,假设目前暂停在A行的double:

const number = 3;
const result = double(number); // A
console.log(result); // D

function double(n) {
  const result = n * 2; // B
  return result; // C
}

点击图示后会执行double内的所有程式码并停在D行的console.log。

在这里插入图片描述

Step into next function call

如果即将执行的Function正是问题所在,Step into会停在该Function内的第一行。

假设目前暂停在A 行的 double

const number = 3;
const result = double(number); // A
console.log(result); // D

function double(n) {
  const result = n * 2; // B
  return result; // C
}

点击图示后会跳至B行,也就是double的第一行。
在这里插入图片描述

Step out of current function

确定目前所在的Function没有问题时,Step out会停在所处Function的后方。

假设目前暂停在double内的B行

const number = 3;
const result = double(number); // A
console.log(result); // D

function double(n) {
  const result = n * 2; // B
  return result; // C
}

点击图示后会执行完目前Function内剩下的程式码,跳至D行的console.log。

在这里插入图片描述

非同步代码

在同步的状况下Step into next function call和Step的行为完全相同,遇到非Built-in Function就会进入,但非同步的状况则有以下区别:

Step into – 执行完同步的程式码,进入非同步的程式码
Step – 跳至下一行同步的程式码
以下方包含非同步行为的程式码为例,直接执行的话数字为以2、3、1 的顺序印出,假设目前停在A 行:

setTimeout(() => console.log(1), 2000); // A
console.log(2); // B
console.log(3); // C

按下Step into会进入setTimeout中的Callback,也就是执行完B、C行,停在D行。

在这里插入图片描述
有注意到中间停了2 秒才再次停止吗?

按下Step会跳至B行,持续按下Step则会停在C、D行。
在这里插入图片描述
执行完setTimeout后已经过了2秒,console.log(1)就直接执行了。

两种Step的差别在于Step into为了进入Function内非同步的程式码,需执行完同步的部分,而step则会停在下一行同步的程式码,不直接进入非同步的部分。

多执行绪(Threads)
当程式码包含多执行绪时,Step into和Step的行为也会有所区别。

以Worker 开启另一个执行绪为例子,假设目前停在A 行:

// index.js
new Worker('worker.js'); // A
console.log('Hello World!'); // B

// worker.js
console.log('Hello Worker!'); // W

按下Step into会直接打开worker.js并停在W行,注意此时已经执行完B行了。

在这里插入图片描述
按下Step会跳至B行,再按一下Step会停在W行。
在这里插入图片描述
注意Sources 面板的右上角会看到多个Thread,Console 面板的Context 也会被切换至Worker。

Hello World!
Hello Worker!

不暂停
若想要暂时关闭断点可以透过Breakpoints列表中的Checkbox开关各个断点或点击上方的Deactivate breakpoints关闭全部,另外可以在程式码行号按下右键选择Never pause here来避免debugger关键字触发暂停。

多断点
刚才的例子都以A、B 等行号来标示暂停的位置,不过要注意在一行有多个Function 的状况下,可以分别在function 前分别建立断点。

function a() {
  console.log('a');
  return 1;
}
function b() {
  console.log('b')
  return 2;
}
console.log(a() + b());

在没有建立断点的情况下,Step over会直接跳至下一行,在bFunction前加入断点或是使用Step into执行完aFunction才能让程式码执行暂停在后方的bFunction前。

在这里插入图片描述
在这里插入图片描述

小结

善用今天提到的跳转、逐步执行功能,就能任意控制程式码的执行来Debug,相较不能中断又很吃参数内容的console.log是不是强大许多呢?

不过除了逐步执行外,还有回溯、断点管理等功能,下一篇文章将会继续介绍JavaScript Debugger 其他重要的功能。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mikes zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值