使用 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 高效調試事先不了解的代碼。 干得不錯!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM