• 使用 Visual Studio Code 进行调试


    现在是时候实践你新获得的调试知识了。 我们刚好有一个完美的机会。 在我们的 Tailwind Traders 应用中,我们正在开发一项新功能:允许以多种货币显示产品的价格。 一位同事为这一目的编写了一些代码,但却没办法找出是哪里出了问题。 我们来帮帮忙。

    在计算机上打开 Visual Studio Code,并使用以下代码创建名为 currency.js 的新文件:

    const rates = {};
    
    function setExchangeRate(rate, sourceCurrency, targetCurrency) {
      if (rates[sourceCurrency] === undefined) {
        rates[sourceCurrency] = {};
      }
    
      if (rates[targetCurrency] === undefined) {
        rates[targetCurrency] = {};
      }
    
      rates[sourceCurrency][targetCurrency] = rate;
      rates[targetCurrency][sourceCurrency] = 1 / rate;
    }
    
    function convertToCurrency(value, sourceCurrency, targetCurrency) {
      const exchangeRate = rates[sourceCurrency][targetCurrency];
      return exchangeRate && value * exchangeRate;
    }
    
    function formatValueForDisplay(value) {
      return value.toFixed(2);
    }
    
    function printForeignValues(value, sourceCurrency) {
      console.info(`The value of ${value} ${sourceCurrency} is:`);
    
      for (const targetCurrency in rates) {
        if (targetCurrency !== sourceCurrency) {
          const convertedValue = convertToCurrency(value, sourceCurrency, targetCurrency);
          const displayValue = formatValueForDisplay(convertedValue);
          console.info(`- ${convertedValue} ${targetCurrency}`);
        }
      }
    }
    
    setExchangeRate(0.88, 'USD', 'EUR');
    setExchangeRate(107.4, 'USD', 'JPY');
    printForeignValues(10, 'EUR');

    要保存该文件,请按“Ctrl+S”(Windows、Linux)或“Cmd+S”(Mac)

    此程序的目标是设置三种货币(USD、EUR 和 JPY)之间的汇率。 然后,我们要显示 10 EUR 对应于其他所有货币的价值,精确到小数点后两位。 对于添加的每种货币,应计算与所有其他货币的汇率。

    创建启动配置

    我们会经常用到调试器,因此让我们为应用创建一个启动配置。 在 Visual Studio Code 中,转到“运行”选项卡,选择“创建 launch.json 文件”,然后选择“Node.js”。

    这就在项目中创建了文件 .vscode/launch.json。 可以编辑此文件,以进一步自定义如何启动程序进行调试。 默认情况下,将创建启动配置以执行当前打开的文件。 在本示例中,该文件为 currency.js

    检查程序入口点的路径和名称是否与设置相匹配。

     备注

    如果要为项目创建不同的启动配置,选择“添加配置”。

    完成配置准备后,若要选择它,请使用边栏顶部的下拉列表。 接下来,要开始调试,请选择“运行”。

    分析问题

    现在,要启动该程序,请选择“启动调试”。

    应看到程序快速完成。 这是正常的,因为尚未添加任何断点。

    如果没有显示调试控制台,若要打开它,请按“Ctrl+Shift+Y”(Windows、Linux)或“Cmd+Shift+Y”(Mac)。 应在调试控制台中看到此文本,后跟一个异常。

    The value of 10 EUR is:
    11.363636363636365
    - 11.363636363636365 USD
    /app/node-101/currency.js:23
      return value.toFixed(2);
                   ^
    TypeError: Cannot read property 'toFixed' of undefined
        at formatValueForDisplay (/app/node-101/currency.js:23:16)
        at printForeignValues (/app/node-101/currency.js:32:28)
        at Object.<anonymous> (/app/node-101/currency.js:40:1)
        at Module._compile (internal/modules/cjs/loader.js:959:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
        at Module.load (internal/modules/cjs/loader.js:815:32)
        at Function.Module._load (internal/modules/cjs/loader.js:727:14)
        at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
        at internal/main/run_main_module.js:17:11

    此程序所要做的是设置三种货币(USD、EUR、JPY)之间的汇率,并显示 10 EUR 对应于其他所有货币的值,精确到小数点后两位。

    在这里可以看到两个 bug:

    • 小数点后不止两位。
    • 程序崩溃并出现异常,无法显示 JPY 值。

    修复位数显示

    首先,我们将解决第一个问题。 由于你没有编写此代码,并且调用了许多不同的函数,因此让我们首先使用分布执行来了解执行流。

    使用断点并逐步执行

    要添加断点,请单击 上第 39 行的左边距。

    然后再次启动调试,并单步执行 printForeignValues() 函数。

    检查变量状态

    现在,使用“变量”窗格检查不同变量的值。

    • value 和 sourceCurrency 的值是多少?
    • 你是否在 rates 变量中看到三个预期的项:USDEUR 和 JPY

    要继续单步执行直至设置变量 convertedValue,请使用“单步跳过”。

    应该看到此时该值似乎正确。

    进一步看看 displayValue 的值。 它应该包含要显示的格式化字符串,如我们预期的那样有两个数字。

    然后我们可以得出结论,到目前为止,函数 convertToCurrency() 和 formatValueForDisplay() 似乎是正确的,并返回了预期的结果。

    更正错误

    继续单步执行直到 console.info() 调用,并仔细检查此行。 看到这里的错误了吗?

    然后你可以在打印值时使用 displayValue 而不是 convertedValue 来修复第一个 bug。 重启程序并检查 USD 值是否正确显示 11.36。 第一个问题解决了。

    找出崩溃的原因

    现在让我们弄清楚程序崩溃的原因。 删除当前断点,并选中“断点”窗格中的 框,以强制程序在引发异常后暂停。

    在调试器中再次运行该程序。 它应在出现异常时暂停,并在编辑器窗口的中间显示一个大型错误日志。

    查看执行停止和显示异常消息 TypeError: Cannot read property 'toFixed' of undefined 的行。 通过该消息可以推断,value 参数函数的值是 undefined 而不是数字,因此导致了异常。

    倒回调用堆栈

    你在错误消息下面看到的堆栈跟踪可能有点难以理解。 好消息是,Visual Studio Code 会为你处理函数调用堆栈。 默认情况下,“调用堆栈”窗格中只会显示有意义的信息。 让我们使用它来找出导致此异常的代码。

    我们知道 formatValueForDisplay() 引发了异常。 要查看调用它的位置,请在“调用堆栈”窗格中双击它下面的函数。 应在 printForeignValues 函数中的此行结束。

    const displayValue = formatValueForDisplay(convertedValue);

    仔细观察,你会发现导致异常的参数来自于 convertedValue 变量。 现在,需要找出该值在何时变为 undefined

    一种选择是在此行添加一个断点,并在断点每次命中该变量时检查它。 我们不知道何时会发生这种情况,在复杂的程序中,这种方法可能很麻烦。

    添加条件断点

    此处最好将调试器设置为仅在 convertedValue 为 undefined 时才在该断点处停止。 事实上,Visual Studio Code 可以做到这一点。 不通过左键单击在 31 行添加常规断点,而是右键单击并选择“添加条件断点”。

    现在可以输入触发断点的条件。 输入 convertedValue === undefined,然后按 Enter。 重启程序,它应在你希望的位置停止。

    观察当前状态

    现在,请花一些时间来分析当前状态。

    • 变量 convertedValue 是 convertToCurrency(value, sourceCurrency, targetCurrency) 的结果,因此还要检查参数的值并确认它们是正确的。
    • 具体而言,请查看 value 是否具有预期的值 10

    查看一下 convertToCurrency() 函数的代码。

    function convertToCurrency(value, sourceCurrency, targetCurrency) {
      const exchangeRate = rates[sourceCurrency][targetCurrency];
      return exchangeRate && value * exchangeRate;
    }

    你知道此代码的结果为 undefined。 还知道 value 为 10。 这意味着问题应该出在 exchangeRate 的值。 将鼠标悬停在变量 rates 之上查看该值。

    你尝试获取 EUR 到 JPY 的汇率,但如果展开 EUR 值,你会发现只有 USD 的转换率。 缺少 JPY 的转换率。

    修复缺失的转换率

    现在已知缺失某些转换率,让我们来了解原因。 要删除所有现有断点,请在“断点”窗格中选择“删除所有断点”。

    观察汇率变量

    在程序的开头第 37 行的 setExchangeRate(0.88, 'USD', 'EUR'); 上添加一个断点。 重启程序,若要监视 rates 变量的值,请在“监视”窗格中选择“加号”并输入 。 每次更新 rates 的值时,其值都会反映在“监视”窗格中。

    单步跳过第一个 setExchangeRate() 调用,并查看 rates 上的结果。

    此时可以看到 USD 和 EUR 的互汇率相同,符合我们的预期。 现在再单步跳过一次,看看第二次 setExchangeRate() 调用的结果。

    你会看到 USD 和 JPY 的互汇率相等,但并未显示 EUR 和 JPY 之间的汇率。 现在来看看 setExchangeRate() 代码。

    function setExchangeRate(rate, sourceCurrency, targetCurrency) {
      if (rates[sourceCurrency] === undefined) {
        rates[sourceCurrency] = {};
      }
    
      if (rates[targetCurrency] === undefined) {
        rates[targetCurrency] = {};
      }
    
      rates[sourceCurrency][targetCurrency] = rate;
      rates[targetCurrency][sourceCurrency] = 1 / rate;
    }

    最重要的是最后两行。 看来你找到 bug了! 仅在 sourceCurrency 和 targetCurrency 之间设定了汇率,但还需要计算之前添加的其他货币的汇率。

    修复代码

    替换以下两行:

    rates[sourceCurrency][targetCurrency] = rate;
    rates[targetCurrency][sourceCurrency] = 1 / rate;

    替换为此代码。

    for (const currency in rates) {
        if (currency !== targetCurrency) {
          // Use a pivot rate for currencies that don't have the direct conversion rate
          const pivotRate = currency === sourceCurrency ? 1 : rates[currency][sourceCurrency];
          rates[currency][targetCurrency] = rate * pivotRate;
          rates[targetCurrency][currency] = 1 / (rate * pivotRate);
        }
      }

    使用此代码,对于 sourceCurrency 和 targetCurrency 以外的每种货币,将使用 sourceCurrency 的汇率来推断另一种货币与 targetCurrency 之间的汇率,并相应地进行设置。

     备注

    只有当 sourceCurrency 和其他货币之间的汇率已经存在时,此修复才有效,在本例中,这是一个可以接受的限制。

    测试更正

    我们来测试一下更改。 删除所有断点,然后重启程序。 现在应在控制台中看到预期的结果,而不会出现任何故障。

    The value of 10 EUR is:
    - 11.36 USD
    - 1220.45 JPY

    就是这样。 代码修复了。 现在,你可以使用 Visual Studio Code 高效调试事先不了解的代码。 干得不错!

     
  • 相关阅读:
    go基础系列~定义新的数据类型
    go基础类型map类型
    redis基础系列~基础监控模板
    事务的隔离级别
    ASP.NET Core 中间件的几种实现方式
    asp.net core 认证和授权实例详解
    快速理解ASP.NET Core的认证与授权
    C# Hashtable、HashSet和Dictionary的区别
    C# 中使用 Redis 简单存储
    ASP.NET Core 中间件
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/16046325.html
Copyright © 2020-2023  润新知