LUR緩存實現
以下是 JavaScript 實現 LRU 緩存的詳細解析,結合核心原理與代碼實現,并標注來源:
一、LRU 緩存核心原理
LRU(Least Recently Used)緩存淘汰策略的核心思想是:當緩存容量滿時,優先淘汰最久未使用的數據。其實現需滿足以下要求:
- 快速訪問:
get
和put
操作需達到 O(1) 時間復雜度。 - 動態調整順序:訪問數據時需將其移動到“最近使用”位置。
class LRUCache {constructor(capacity) {this.cache = new Map();this.capacity = capacity;}get(key) {if (!this.cache.has(key)) return -1;const value = this.cache.get(key);this.cache.delete(key); // 刪除后重新插入保證順序this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) this.cache.delete(key);this.cache.set(key, value);if (this.cache.size > this.capacity) {// 刪除最久未使用的鍵(Map的迭代順序保證)this.cache.delete(this.cache.keys().next().value);}}
}
二、JavaScript 實現方案
1. 基于 Map 的實現(推薦)
JavaScript 的 Map
對象天然保持鍵的插入順序,迭代時按插入順序返回鍵。利用這一特性,可實現簡潔的 LRU 緩存。
代碼實現:
class LRUCache {constructor(capacity) {this.capacity = capacity;this.cache = new Map();}get(key) {if (!this.cache.has(key)) return -1;// 訪問后移動到尾部(最近使用)const value = this.cache.get(key);this.cache.delete(key);this.cache.set(key, value);return value;}put(key, value) {if (this.cache.has(key)) {// 更新值并移動到尾部this.cache.delete(key);} else if (this.cache.size >= this.capacity) {// 緩存滿時刪除頭部(最久未使用)this.cache.delete(this.cache.keys().next().value);}// 插入新鍵到尾部this.cache.set(key, value);}
}
關鍵操作解析:
? get
方法:若鍵存在,刪除舊值并重新插入到尾部,表示最近訪問過。
? put
方法:若鍵存在,更新值并調整位置;若不存在,插入新鍵。若超出容量,刪除頭部鍵。
2. 基于雙向鏈表 + Map 的實現
通過自定義雙向鏈表節點和鏈表類,可更直觀地維護節點順序。
代碼實現:
class Node {constructor(key, value) {this.key = key;this.value = value;this.prev = null;this.next = null;}
}class LRUCache {constructor(capacity) {this.capacity = capacity;this.map = new Map();this.head = new Node(0, 0); // 頭哨兵this.tail = new Node(0, 0); // 尾哨兵this.head.next = this.tail;this.tail.prev = this.head;}get(key) {if (!this.map.has(key)) return -1;const node = this.map.get(key);this.moveToHead(node);return node.value;}put(key, value) {if (this.map.has(key)) {const node = this.map.get(key);node.value = value;this.moveToHead(node);} else {const newNode = new Node(key, value);this.map.set(key, newNode);this.addToHead(newNode);if (this.map.size > this.capacity) {const lruNode = this.removeTail();this.map.delete(lruNode.key);}}}moveToHead(node) {this.removeNode(node);this.addToHead(node);}removeNode(node) {node.prev.next = node.next;node.next.prev = node.prev;}addToHead(node) {node.next = this.head.next;node.prev = this.head;this.head.next.prev = node;this.head.next = node;}removeTail() {const node = this.tail.prev;this.removeNode(node);return node;}
}
關鍵操作解析:
? 雙向鏈表:維護節點順序,addToHead
和 removeNode
操作均為 O(1)。
? get
方法:訪問節點后將其移動到頭部。
? put
方法:插入新節點到頭部,超出容量時刪除尾部節點。
三、性能分析
? 時間復雜度:get
和 put
均為 O(1),因 Map 和雙向鏈表的插入/刪除操作均為常數時間。
? 空間復雜度:O(capacity),需存儲所有緩存項。
四、擴展與優化
- 惰性刪除:結合
WeakMap
實現惰性過期,自動清理過期數據。 - 并發控制:在高并發場景中,使用鎖機制或線程安全容器(如
synchronized
包)。 - 容量動態調整:根據系統負載動態調整緩存容量。
總結
JavaScript 實現 LRU 緩存的核心在于 Map + 雙向鏈表 的組合,或直接利用 Map
的有序特性。推薦使用第一種方案(基于 Map),代碼簡潔且性能高效。如需更復雜的緩存策略(如 TTL),可參考 Node.js 的 lru-cache
庫。
new關鍵字實現
以下是 JavaScript 實現 new
操作符的詳細解析,結合核心原理與代碼實現,并標注來源:
一、new
操作符的核心作用
new
操作符用于創建一個構造函數的實例對象,并完成以下任務:
- 創建新對象:生成一個空對象。
- 綁定原型鏈:將新對象的原型指向構造函數的
prototype
。 - 綁定
this
:將構造函數內部的this
綁定到新對象。 - 處理返回值:若構造函數返回對象,則返回該對象;否則返回新創建的對象。
二、new
的執行流程
-
創建新對象
const obj = {}; // 或 Object.create(Constructor.prototype)
生成一個空對象,后續通過原型鏈繼承構造函數的方法。
-
設置原型鏈
obj.__proto__ = Constructor.prototype; // 或 Object.setPrototypeOf(obj, Constructor.prototype)
使新對象可訪問構造函數原型上的屬性和方法。
-
綁定
this
并執行構造函數const result = Constructor.apply(obj, args);
將構造函數的
this
綁定到新對象,并傳入參數執行。 -
返回結果
return result instanceof Object ? result : obj;
若構造函數返回對象,則返回該對象;否則返回新創建的對象。
三、手寫 new
操作符的實現
基礎版本
function myNew(Constructor, ...args) {const obj = Object.create(Constructor.prototype); // const result = Constructor.apply(obj, args); // return result instanceof Object ? result : obj; //
}
優化版本
增加類型檢查與錯誤處理:
function myNew(Constructor, ...args) {if (typeof Constructor !== 'function') {throw new TypeError('Constructor must be a function');}const obj = Object.create(Constructor.prototype);try {return Constructor.apply(obj, args);} catch (error) {throw error;}
}
四、特殊情況與注意事項
-
構造函數返回值的影響
? 若返回原始值(如數字、字符串),new
會忽略并返回新對象。
? 若返回對象,則直接返回該對象(原型鏈斷裂)。function Test() { return { foo: 'bar' }; } const t = new Test(); // t 是 { foo: 'bar' }, 而非 Test 的實例
-
忘記使用
new
的問題
直接調用構造函數會導致this
指向全局對象(如window
),引發全局變量污染。function Person() { this.name = '張三'; } Person(); // window.name = '張三'
-
箭頭函數的限制
箭頭函數沒有自己的this
,無法作為構造函數使用。const Person = (name) => { this.name = name; }; new Person(); // TypeError: Person is not a constructor
五、實際應用場景
-
創建對象實例
function User(name, role) { this.name = name; this.role = role; } const admin = new User('admin', 'administrator');
-
實現繼承
function Animal(name) { this.name = name; } function Dog(name, breed) {Animal.call(this, name); // 調用父類構造函數this.breed = breed; } Dog.prototype = Object.create(Animal.prototype); // 設置原型鏈
總結
new
操作符通過 創建對象→綁定原型→綁定 this
→處理返回值 四步實現實例化。手寫實現時需注意類型檢查、錯誤處理及返回值判斷。理解其原理有助于掌握 JavaScript 的面向對象編程,并在面試中應對相關問題。
大數相加
-
字符串逐位相加:將大數轉換為字符串,逐位相加并處理進位。這在多個網頁中都有提到,比如網頁[1]、[6]、[7]、[8]都詳細描述了這種方法。特別是網頁[7]和[8]提供了具體的代碼示例,應該引用這些網頁。
-
使用BigInt類型:網頁[5]和[4]提到,BigInt可以處理任意精度的整數,但只能用于整數,不能處理小數。需要指出這一點,并引用相關網頁。
-
第三方庫:網頁[1]、[2]、[3]、[4]、[5]都推薦了decimal.js、bignumber.js等庫,這些庫專門處理高精度計算,適合復雜場景。需要引用這些網頁中的例子,比如網頁[1]提到的bignumber.js和網頁[2]中的decimal.js。
-
轉換為整數計算:網頁[2]、[3]、[4]提到將小數轉換為整數進行計算,適用于固定小數位數的場景。例如,網頁[2]中的示例代碼展示了這種方法,需要引用網頁[2]。
-
處理特殊情況:比如進位處理和結果反轉,這在網頁[6]、[7]、[8]的代碼示例中都有體現,需要指出這些細節并引用對應的網頁。
以下是 JavaScript 實現大數相加(精度處理) 的詳細解決方案,結合不同場景需求與實現原理:
一、核心問題與解決方案分類
JavaScript 的 Number
類型基于 IEEE 754 雙精度浮點數表示,無法精確處理超過 2^53-1 的整數或高精度小數。大數相加的精度問題主要表現為:
? 整數溢出:如 9007199254740992 + 1 = 9007199254740992
(超出安全整數范圍)。
? 浮點數精度丟失:如 0.1 + 0.2 = 0.30000000000000004
。
二、主要實現方案
1. 字符串逐位相加(推薦)
原理:將大數轉換為字符串,逐位模擬手工加法,處理進位。
代碼實現:
function addLargeNumbers(num1, num2) {const a = num1.toString().split('').reverse();const b = num2.toString().split('').reverse();let carry = 0;const maxLength = Math.max(a.length, b.length);const result = [];for (let i = 0; i < maxLength; i++) {const digit1 = parseInt(a[i] || 0, 10);const digit2 = parseInt(b[i] || 0, 10);const sum = digit1 + digit2 + carry;result.push(sum % 10);carry = Math.floor(sum / 10);}if (carry > 0) result.push(carry);return result.reverse().join('');
}
特點:
? 支持任意長度整數相加。
? 時間復雜度 O(n),性能高效。
? 需手動處理進位與結果反轉。
2. 使用 BigInt 類型
原理:ES6 引入的 BigInt
可表示任意精度整數,但僅支持整數運算。
代碼示例:
const num1 = BigInt("9007199254740992");
const num2 = BigInt("1");
console.log(num1 + num2); // 輸出: 9007199254740993n
特點:
? 無需手動處理進位,語法簡潔。
? 無法直接與 Number
類型運算,需顯式轉換。
3. 第三方高精度庫
推薦庫:
? decimal.js:支持任意精度十進制運算,適合金融場景。
const Decimal = require('decimal.js');
const result = new Decimal('0.1').plus('0.2');
console.log(result.toString()); // 輸出: 0.3
? bignumber.js:提供豐富的 API,支持科學計算。
const BigNumber = require('bignumber.js');
const num1 = new BigNumber('9999999999999999999999999999999999999999999999999999999999999');
console.log(num1.plus(1).toString()); // 輸出: 10000000000000000000000000000000000000000000000000000000000000
優勢:
? 內置四舍五入、指數運算等復雜功能。
? 避免手動實現進位邏輯的復雜性。
4. 轉換為整數計算(固定小數位數)
適用場景:需精確控制小數位數(如貨幣計算)。
實現方法:
function addWithPrecision(num1, num2, precision = 2) {const factor = Math.pow(10, precision);return (Math.round(num1 * factor) + Math.round(num2 * factor)) / factor;
}
console.log(addWithPrecision(0.1, 0.2)); // 輸出: 0.3
特點:
? 通過整數運算避免浮點數誤差。
? 需提前確定精度,靈活性較低。
三、性能與場景選擇
方案 | 適用場景 | 性能 | 代碼復雜度 |
---|---|---|---|
字符串逐位相加 | 任意長度整數相加 | 中等 | 高 |
BigInt | 任意長度整數(僅整數運算) | 高 | 低 |
第三方庫 | 復雜運算(金融、科學計算) | 中等 | 低 |
轉換為整數 | 固定小數位數計算 | 高 | 低 |
推薦選擇:
? 簡單場景:字符串逐位相加。
? 金融/科學計算:使用 decimal.js
或 bignumber.js
。
? 大整數運算:直接使用 BigInt
。
四、擴展與注意事項
- 處理負數:需在逐位相加前統一符號,并單獨處理負號。
- 結果格式化:使用
toFixed()
或庫內置方法控制小數位數。 - 性能優化:對超長數字可分段并行計算(如 Web Worker)。
通過以上方案,可靈活應對 JavaScript 中的大數精度問題。如需完整代碼示例或庫的安裝指南,可參考對應網頁。
最長遞增子序列(Vue3 Diff)
動態規劃
以下是 JavaScript 實現最長遞增子序列(LIS) 的詳細解析,結合動態規劃與優化算法,并標注來源:
一、問題描述
給定一個整數數組 nums
,找到其中最長嚴格遞增子序列的長度。子序列無需連續,但必須保持元素順序。例如:
? 輸入 [10,9,2,5,3,7,101,18]
,輸出 4
(子序列 [2,3,7,101]
)。
二、動態規劃解法(O(n2))
核心思路
- 定義狀態:
dp[i]
表示以nums[i]
結尾的最長遞增子序列長度。 - 狀態轉移:遍歷數組,若
nums[i] > nums[j]
(j < i
),則更新dp[i] = max(dp[i], dp[j] + 1)
。 - 結果:遍歷
dp
數組,取最大值即為 LIS 長度。
代碼實現
function lengthOfLIS(nums) {const n = nums.length;if (n === 0) return 0;const dp = new Array(n).fill(1); // 初始化為1,每個元素自身構成子序列let maxLen = 1;for (let i = 1; i < n; i++) {for (let j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}maxLen = Math.max(maxLen, dp[i]);}return maxLen;
}
三、優化解法(O(nlogn))
核心思路
- 維護有序數組:
tails[i]
表示長度為i+1
的所有遞增子序列的最小尾部元素。 - 二分查找:遍歷數組,通過二分查找找到
tails
中第一個大于等于當前元素的位置,更新或插入元素。
代碼實現
function lengthOfLIS(nums) {const tails = [];for (const num of nums) {const pos = binarySearch(tails, num);if (pos === tails.length) {tails.push(num);} else {tails[pos] = num;}}return tails.length;
}function binarySearch(arr, target) {let left = 0, right = arr.length;while (left < right) {const mid = Math.floor((left + right) / 2);if (arr[mid] < target) left = mid + 1;else right = mid;}return left;
}
四、性能對比
算法 | 時間復雜度 | 空間復雜度 | 適用場景 |
---|---|---|---|
動態規劃 | O(n2) | O(n) | 小規模數據(n ≤ 1000) |
優化算法(二分) | O(nlogn) | O(n) | 大規模數據(n ≥ 1000) |
五、擴展與注意事項
-
嚴格遞增 vs 非嚴格遞增
? 嚴格遞增:nums[i] > nums[j]
(如示例1)。
? 非嚴格遞增:nums[i] ≥ nums[j]
(需調整條件)。 -
返回子序列本身
? 動態規劃可記錄路徑,但需額外空間。
? 優化算法需逆向重建路徑。 -
邊界條件處理
? 空數組返回0,單個元素返回1。
總結
? 簡單場景:優先使用動態規劃(代碼簡潔,易理解)。
? 高效場景:選擇 O(nlogn) 優化算法(處理大規模數據)。
? 理解兩種算法的原理差異,可應對不同性能需求。
高并發請求控制
高并發請求控制
大文件分片上傳實現(斷點續傳)
核心流程(網頁)
1.文件切片:將文件按固定大小(如5MB)分割
2. 哈希生成:使用SparkMD5等庫生成文件唯一標識
3. 分片上傳:并發控制上傳切片(通常限制5個并發)
4. 斷點續傳:通過本地存儲記錄已上傳切片
5.服務端合并:所有切片上傳完成后觸發合并請求
// 文件切片(網頁5)
function sliceFile(file, chunkSize = 5 * 1024 * 1024) {const chunks = [];let start = 0;while (start < file.size) {chunks.push(file.slice(start, start + chunkSize));start += chunkSize;}return chunks;
}// 分片上傳(網頁6)
async function uploadChunks(fileHash, chunks) {const maxConcurrent = 5; // 最大并發數const uploaded = await checkUploadedChunks(fileHash);for (let i = 0; i < chunks.length; i += maxConcurrent) {await Promise.all(chunks.slice(i, i + maxConcurrent).map(async (chunk, index) => {if (!uploaded.includes(i + index)) {const formData = new FormData();formData.append('chunk', chunk);formData.append('hash', `${fileHash}-${i + index}`);await fetch('/upload', { method: 'POST', body: formData });}}));}await mergeChunks(fileHash, file.name);
}
以下是 JavaScript 實現大文件分片上傳(斷點續傳) 的詳細解析,結合核心原理與代碼實現,并標注來源:
一、核心實現步驟
-
文件切片
將大文件分割成固定大小的塊(如 5MB),使用File.slice()
方法實現。function createFileChunks(file, chunkSize = 5 * 1024 * 1024) {const chunks = [];let start = 0;while (start < file.size) {chunks.push(file.slice(start, start + chunkSize));start += chunkSize;}return chunks; }
-
生成文件唯一標識
通過文件名、大小和最后修改時間生成唯一標識(避免 MD5 計算耗時)。function calculateFileHash(file) {return `${file.name}-${file.size}-${file.lastModified}`; }
-
檢查已上傳切片
通過本地存儲(localStorage
)或服務器查詢已上傳的切片索引,跳過已上傳部分。const uploadedChunks = JSON.parse(localStorage.getItem(fileHash)) || [];
-
并發上傳切片
使用Promise.all
并發上傳未上傳的切片,控制并發數(如 5 個)。const maxConcurrent = 5; const uploadQueue = chunks.filter((_, index) => !uploadedChunks.includes(index)).map((chunk, index) => uploadChunk(chunk, index)); await Promise.all(uploadQueue);
-
合并切片與清理進度
所有切片上傳完成后,調用服務器合并接口,并清理本地進度記錄。await fetch('/merge', {method: 'POST',body: JSON.stringify({ fileHash, filename: file.name }) }); localStorage.removeItem(fileHash);
二、關鍵技術點
-
文件哈希計算
使用spark-md5
庫計算文件全量哈希,實現秒傳功能。// 主線程 calculateHash(chunkList).then(hash => {if (serverFileExists(hash)) return; // 秒傳 });
-
進度存儲
通過localStorage
記錄已上傳切片索引,支持斷點續傳。uploadProgress.save(fileHash, uploadedChunks);
-
并發控制
通過隊列機制限制同時上傳的切片數量,避免瀏覽器崩潰。let activeUploads = 0; function processQueue() {if (activeUploads < maxConcurrent && uploadQueue.length > 0) {// 上傳邏輯} }
-
錯誤處理與重試
捕獲上傳失敗切片,支持自動重試或手動重傳。try {await uploadChunk(chunk); } catch (error) {retryUpload(chunk); }
-
秒傳功能
服務器端校驗文件哈希,若存在則直接返回成功,避免重復上傳。if (serverFileExists(fileHash)) {return { success: true, message: '秒傳成功' }; }
三、完整代碼示例
<input type="file" id="fileInput" />
<button id="uploadBtn">上傳</button>
<progress id="progressBar" value="0" max="100"></progress><script>const fileInput = document.getElementById('fileInput');const progressBar = document.getElementById('progressBar');const axios = require('axios');document.getElementById('uploadBtn').onclick = async () => {const file = fileInput.files[0];const chunkSize = 10 * 1024 * 1024; // 10MBconst chunks = fileToChunks(file, chunkSize);const fileHash = calculateFileHash(file);// 檢查已上傳切片const uploadedChunks = JSON.parse(localStorage.getItem(fileHash)) || [];// 并發上傳未上傳切片const promises = chunks.map((chunk, index) => {if (uploadedChunks.includes(index)) return Promise.resolve();return uploadChunk(chunk, index, fileHash);});await Promise.all(promises);// 合并切片await axios.post('/merge', { fileHash, filename: file.name });localStorage.removeItem(fileHash);progressBar.value = 100;};function fileToChunks(file, size) {const chunks = [];for (let start = 0; start < file.size; start += size) {chunks.push(file.slice(start, start + size));}return chunks;}function calculateFileHash(file) {return `${file.name}-${file.size}-${file.lastModified}`;}async function uploadChunk(chunk, index, fileHash) {const formData = new FormData();formData.append('chunk', chunk);formData.append('index', index);formData.append('fileHash', fileHash);try {await axios.post('/upload', formData);localStorage.setItem(fileHash, JSON.stringify([...JSON.parse(localStorage.getItem(fileHash) || '[]'), index]));progressBar.max = chunks.length;progressBar.value++;} catch (error) {console.error(`Chunk ${index} 上傳失敗`);}}
</script>
四、注意事項
-
切片大小選擇
建議 2-10MB,太小增加請求次數,太大增加重試成本。 -
服務器端配合
需提供以下接口:
?/upload
:上傳單個切片
?/merge
:合并切片
?/check
:查詢已上傳切片 -
瀏覽器兼容性
File.slice()
在 IE10+ 支持,低版本需使用Blob.slice()
。 -
網絡中斷處理
可結合visibilitychange
事件暫停/恢復上傳。
五、性能優化建議
方案 | 效果 | 實現復雜度 |
---|---|---|
分片大小動態調整 | 平衡上傳速度與穩定性 | 中 |
上傳進度可視化 | 提升用戶體驗 | 低 |
錯誤重試機制 | 減少因網絡波動導致的失敗 | 中 |
壓縮切片數據 | 減少傳輸數據量 | 高 |
通過以上方案,可實現高效、可靠的大文件分片上傳。實際開發中需結合具體業務場景選擇優化策略,并確保前后端接口的兼容性。
Web Worker
以下是 JavaScript Web Worker 通信機制 的詳細解析,結合主線程與 Worker 交互的核心原理與實現方法,并標注來源:
一、Web Worker 核心概念
Web Worker 是瀏覽器提供的多線程解決方案,允許在后臺線程中執行 JavaScript 代碼,避免阻塞主線程。其核心特點包括:
- 線程隔離:Worker 線程與主線程完全隔離,無法直接訪問 DOM、
window
等全局對象。 - 消息傳遞:通過
postMessage
和onmessage
實現異步通信,數據通過結構化克隆算法傳輸。 - 類型分類:
? Dedicated Worker:僅服務于創建它的主線程。
? Shared Worker:跨頁面共享,支持多標簽頁通信。
二、主線程與 Worker 交互流程
1. 創建 Worker 實例
主線程通過 new Worker(url)
創建 Worker,url
指向 Worker 腳本文件(需同源):
const worker = new Worker('worker.js'); //
2. 發送消息(postMessage)
主線程通過 postMessage
發送數據到 Worker,支持復雜數據類型(對象、數組等):
worker.postMessage({ type: 'calculate', data: [1,2,3] }); //
3. 接收消息(onmessage)
Worker 通過 self.onmessage
監聽主線程消息,并通過 postMessage
返回結果:
// Worker 線程 (worker.js)
self.onmessage = (event) => {const result = event.data.data.reduce((sum, num) => sum + num, 0);self.postMessage(result); //
};
4. 終止 Worker
任務完成后,主線程調用 terminate()
釋放資源:
worker.terminate(); //
三、通信機制關鍵點
1. 數據傳輸機制
? 結構化克隆算法:支持大多數數據類型(如對象、數組、Date),但無法處理函數、DOM 節點等。
? Transferable Objects:通過 transfer
參數直接轉移數據所有權,避免復制開銷(如 ArrayBuffer
):
// 主線程
const buffer = new ArrayBuffer(1024);
worker.postMessage(buffer, [buffer]); //
2. 消息傳遞特性
? 異步非阻塞:消息處理不會阻塞線程。
? 事件驅動:通過 onmessage
和 onerror
處理消息和異常。
3. 共享數據與跨域限制
? 數據隔離:Worker 與主線程無法共享內存,需通過消息傳遞交換數據。
? 同源策略:Worker 腳本需與主線程同源,跨域需通過 CORS 或代理。
四、高級應用場景
-
計算密集型任務:如大數據處理、圖像加密(示例見網頁):
// Worker 線程加密字符串 self.onmessage = (e) => {const encrypted = encrypt(e.data);self.postMessage(encrypted); };
-
跨頁面通信:使用
SharedWorker
實現多標簽頁數據同步(網頁):// 主線程 const sharedWorker = new SharedWorker('shared.js'); sharedWorker.port.onmessage = (e) => console.log(e.data);
-
性能優化:
? 合理控制 Worker 數量,避免資源浪費。
? 使用Transferable Objects
減少大數據傳輸開銷。
五、注意事項
-
錯誤處理:通過
onerror
監聽 Worker 異常:worker.onerror = (error) => console.error('Worker error:', error); //
-
調試技巧:
? 瀏覽器開發者工具的 Sources 面板查看 Worker 代碼。
? 在 Worker 中使用console.log
輸出調試信息。 -
適用性評估:
? 僅處理 CPU 密集型任務,避免因線程創建和通信開銷影響簡單任務。
總結
Web Worker 通過 消息傳遞機制 實現主線程與 Worker 的高效交互,適用于提升復雜計算的性能和頁面響應性。實際開發中需結合任務類型選擇 Worker 類型,并注意數據傳輸優化與錯誤處理。