国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
關(guān)鍵要點(diǎn)
什麼是事件循環(huán)?
半無限循環(huán)
回調(diào)隊(duì)列
使用 async/await 的事件循環(huán)
更進(jìn)一步
事件循環(huán)階段
逐階段演示
線程池
總結(jié)
process.nextTick() 與 setImmediate()
結(jié)論
關(guān)於 Node.js 事件循環(huán)的常見問題
首頁 web前端 js教程 Node.js事件循環(huán):開發(fā)人員的概念和代碼指南

Node.js事件循環(huán):開發(fā)人員的概念和代碼指南

Feb 12, 2025 am 08:36 AM

Node.js 的異步編程:深入理解事件循環(huán)

The Node.js Event Loop: A Developer's Guide to Concepts & Code

異步編程在任何編程語言中都極具挑戰(zhàn)性。並發(fā)、並行和死鎖等概念讓即使是最資深的工程師也感到棘手。異步執(zhí)行的代碼難以預(yù)測,出現(xiàn)bug時也難以追蹤。然而,這個問題是不可避免的,因?yàn)楝F(xiàn)代計算擁有多核處理器。每個CPU內(nèi)核都有其熱限制,單核性能提升已達(dá)到瓶頸。這促使開發(fā)者編寫高效的代碼,充分利用硬件資源。

JavaScript 是單線程的,但這是否限制了 Node.js 利用現(xiàn)代架構(gòu)的能力呢?最大的挑戰(zhàn)之一是處理多線程的固有復(fù)雜性。創(chuàng)建新線程和管理線程間的上下文切換代價高昂。操作系統(tǒng)和程序員都需要付出大量努力才能提供一個處理眾多邊緣情況的解決方案。本文將闡述 Node.js 如何通過事件循環(huán)來解決這個難題,深入探討 Node.js 事件循環(huán)的各個方面並演示其工作原理。事件循環(huán)是 Node.js 的殺手級特性之一,因?yàn)樗砸环N全新的方式解決了這個棘手的問題。

關(guān)鍵要點(diǎn)

  • Node.js 事件循環(huán)是一個單線程、非阻塞和異步並發(fā)的循環(huán),允許高效處理多個任務(wù),而無需等待每個任務(wù)完成。這使得同時處理多個 Web 請求成為可能。
  • 事件循環(huán)是半無限的,這意味著如果調(diào)用?;蚧卣{(diào)隊(duì)列為空,它可以退出。該循環(huán)負(fù)責(zé)輪詢操作系統(tǒng)以獲取來自傳入連接的回調(diào)。
  • 事件循環(huán)在多個階段運(yùn)行:時間戳更新、循環(huán)活躍性檢查、定時器執(zhí)行、待處理回調(diào)執(zhí)行、空閑處理程序執(zhí)行、準(zhǔn)備setImmediate 回調(diào)執(zhí)行的句柄、計算輪詢超時、阻塞I/O 、檢查句柄回調(diào)執(zhí)行、關(guān)閉回調(diào)執(zhí)行以及迭代結(jié)束。
  • Node.js 利用兩個主要部分:V8 JavaScript 引擎和 libuv。網(wǎng)絡(luò) I/O、文件 I/O 和 DNS 查詢通過 libuv 進(jìn)行。線程池中可用於這些任務(wù)的線程數(shù)量有限,可以通過 UV_THREADPOOL_SIZE 環(huán)境變量進(jìn)行設(shè)置。
  • 在每個階段結(jié)束時,循環(huán)執(zhí)行 process.nextTick() 回調(diào),它不是事件循環(huán)的一部分,因?yàn)樗诿總€階段結(jié)束時運(yùn)行。 setImmediate() 回調(diào)是整個事件循環(huán)的一部分,因此它並不像名稱暗示的那樣立即執(zhí)行。一般建議使用 setImmediate()。

什麼是事件循環(huán)?

事件循環(huán)是一個單線程、非阻塞和異步並發(fā)的循環(huán)。對於沒有計算機(jī)科學(xué)學(xué)位的人來說,想像一下一個執(zhí)行數(shù)據(jù)庫查找的 Web 請求。單線程一次只能執(zhí)行一項(xiàng)操作。它不會等待數(shù)據(jù)庫響應(yīng),而是繼續(xù)處理隊(duì)列中的其他任務(wù)。在事件循環(huán)中,主循環(huán)展開調(diào)用棧,並且不等待回調(diào)。由於循環(huán)不會阻塞,因此它可以同時處理多個 Web 請求。多個請求可以同時排隊(duì),使其具有並發(fā)性。循環(huán)不會等待一個請求的所有操作都完成,而是根據(jù)回調(diào)的出現(xiàn)順序進(jìn)行處理,而不會阻塞。

循環(huán)本身是半無限的,這意味著如果調(diào)用?;蚧卣{(diào)隊(duì)列為空,它可以退出循環(huán)。可以將調(diào)用棧視為同步代碼,例如 console.log,在循環(huán)輪詢更多工作之前展開。 Node.js 使用底層的 libuv 來輪詢操作系統(tǒng)以獲取來自傳入連接的回調(diào)。

您可能想知道,為什麼事件循環(huán)在單線程中執(zhí)行?對於每個連接所需的數(shù)據(jù)而言,線程在內(nèi)存中相對較重。線程是操作系統(tǒng)資源,需要啟動,這無法擴(kuò)展到數(shù)千個活動連接。

通常情況下,多線程也會使情況復(fù)雜化。如果回調(diào)返回數(shù)據(jù),它必須將上下文編組回正在執(zhí)行的線程。線程間的上下文切換速度很慢,因?yàn)樗仨毻疆?dāng)前狀態(tài),例如調(diào)用?;蚓植孔兞俊J录h(huán)在多個線程共享資源時可以避免bug,因?yàn)樗鼏尉€程。單線程循環(huán)減少了線程安全邊緣情況,並且可以更快地進(jìn)行上下文切換。這就是循環(huán)背後的真正天才之處。它在保持可擴(kuò)展性的同時有效地利用了連接和線程。

理論足夠了;現(xiàn)在來看看代碼是什麼樣的。您可以隨意在 REPL 中進(jìn)行操作或下載源代碼。

半無限循環(huán)

事件循環(huán)必須回答的最大問題是循環(huán)是否處於活動狀態(tài)。如果是,則確定在回調(diào)隊(duì)列上等待多長時間。在每次迭代中,循環(huán)展開調(diào)用棧,然後進(jìn)行輪詢。

這是一個阻塞主循環(huán)的示例:

setTimeout(
  () => console.log('Hi from the callback queue'),
  5000); // 保持循環(huán)活動這么長時間

const stopTime = Date.now() + 2000;
while (Date.now() < stopTime) {}

如果您運(yùn)行此代碼,請注意循環(huán)被阻塞了兩秒鐘。但是,循環(huán)會保持活動狀態(tài),直到回調(diào)在五秒鐘後執(zhí)行。一旦主循環(huán)解除阻塞,輪詢機(jī)制就會確定它在回調(diào)上等待多長時間。當(dāng)調(diào)用棧展開並且沒有剩餘回調(diào)時,此循環(huán)結(jié)束。

回調(diào)隊(duì)列

現(xiàn)在,當(dāng)我阻塞主循環(huán)然後調(diào)度回調(diào)時會發(fā)生什麼?一旦循環(huán)被阻塞,它就不會將更多回調(diào)添加到隊(duì)列中:

const stopTime = Date.now() + 2000;
while (Date.now() < stopTime) {}
// 這需要 7 秒才能執(zhí)行
setTimeout(() => console.log('Ran callback A'), 5000);

這次循環(huán)保持活動狀態(tài)七秒鐘。事件循環(huán)在其簡單性方面是愚蠢的。它無法知道將來可能會排隊(duì)什麼。在實(shí)際系統(tǒng)中,傳入的回調(diào)會排隊(duì)並在主循環(huán)可以進(jìn)行輪詢時執(zhí)行。事件循環(huán)在解除阻塞時會順序地經(jīng)歷幾個階段。因此,為了在關(guān)於循環(huán)的面試中脫穎而出,請避免使用“事件發(fā)射器”或“反應(yīng)器模式”等花哨的術(shù)語。它是一個簡單的單線程循環(huán),並發(fā)且非阻塞。

使用 async/await 的事件循環(huán)

為了避免阻塞主循環(huán),一個想法是用 async/await 包裝同步 I/O:

const fs = require('fs');
const readFileSync = async (path) => await fs.readFileSync(path);

readFileSync('readme.md').then((data) => console.log(data));
console.log('The event loop continues without blocking...');

await 之後出現(xiàn)的任何內(nèi)容都來自回調(diào)隊(duì)列。代碼看起來像同步阻塞代碼,但它不會阻塞。請注意,async/await 使 readFileSync 成為可 then 的,這將其從主循環(huán)中移除??梢詫?await 之後出現(xiàn)的任何內(nèi)容視為通過回調(diào)進(jìn)行的非阻塞操作。

完全披露:以上代碼僅用於演示目的。在實(shí)際代碼中,我建議使用 fs.readFile,它會觸發(fā)一個可以圍繞 Promise 包裝的回調(diào)??傮w意圖仍然有效,因?yàn)檫@將阻塞 I/O 從主循環(huán)中移除。

更進(jìn)一步

如果我告訴你事件循環(huán)不僅僅是調(diào)用棧和回調(diào)隊(duì)列呢?如果事件循環(huán)不僅僅是一個循環(huán),而是多個循環(huán)呢?如果它可以在底層擁有多個線程呢?

現(xiàn)在,我想帶你深入 Node.js 內(nèi)部。

事件循環(huán)階段

這些是事件循環(huán)階段:

The Node.js Event Loop: A Developer's Guide to Concepts & Code

圖片源:libuv 文檔

  1. 更新時間戳。事件循環(huán)在循環(huán)開始時緩存當(dāng)前時間,以避免頻繁進(jìn)行與時間相關(guān)的系統(tǒng)調(diào)用。這些系統(tǒng)調(diào)用是 libuv 的內(nèi)部調(diào)用。
  2. 循環(huán)是否處於活動狀態(tài)?如果循環(huán)具有活動句柄、活動請求或正在關(guān)閉的句柄,則它處於活動狀態(tài)。如所示,隊(duì)列中的待處理回調(diào)使循環(huán)保持活動狀態(tài)。
  3. 執(zhí)行到期的定時器。這是 setTimeout 或 setInterval 回調(diào)運(yùn)行的地方。循環(huán)檢查緩存的now 以使到期的活動回調(diào)執(zhí)行。
  4. 執(zhí)行隊(duì)列中的待處理回調(diào)。如果之前的迭代延遲了任何回調(diào),則這些回調(diào)會在此時運(yùn)行。輪詢通常會立即運(yùn)行 I/O 回調(diào),但也有例外。此步驟處理來自上一次迭代的任何滯後回調(diào)。
  5. 執(zhí)行空閑處理程序——主要是因?yàn)槊划?dāng),因?yàn)檫@些處理程序在每次迭代中都會運(yùn)行,並且是 libuv 的內(nèi)部處理程序。
  6. 準(zhǔn)備在循環(huán)迭代中執(zhí)行 setImmediate 回調(diào)的句柄。這些句柄在循環(huán)阻塞 I/O 之前運(yùn)行,並為這種回調(diào)類型準(zhǔn)備隊(duì)列。
  7. 計算輪詢超時。循環(huán)必須知道它阻塞 I/O 的時間。這就是它如何計算超時的:
    • 如果循環(huán)即將退出,則超時為 0。
    • 如果沒有活動句柄或請求,則超時為 0。
    • 如果有任何空閒句柄,則超時為 0。
    • 如果隊(duì)列中有任何待處理的句柄,則超時為 0。
    • 如果有任何正在關(guān)閉的句柄,則超時為 0。
    • 如果以上都不是,則超時設(shè)置為最接近的定時器,如果沒有任何活動定時器,則為無限
  8. 循環(huán)使用上一個階段的持續(xù)時間阻塞 I/O。隊(duì)列中的與 I/O 相關(guān)的回調(diào)在此處執(zhí)行。
  9. 執(zhí)行檢查句柄回調(diào)。此階段是 setImmediate 運(yùn)行的階段,它是準(zhǔn)備句柄的對應(yīng)階段。在 I/O 回調(diào)執(zhí)行過程中排隊(duì)的任何 setImmediate 回調(diào)都會在此處運(yùn)行。
  10. 執(zhí)行關(guān)閉回調(diào)。這些是從已關(guān)閉連接中釋放的活動句柄。
  11. 迭代結(jié)束。

您可能想知道為什麼輪詢在應(yīng)該是非阻塞的情況下會阻塞 I/O?只有當(dāng)隊(duì)列中沒有待處理的回調(diào)並且調(diào)用棧為空時,循環(huán)才會阻塞。在 Node.js 中,最接近的定時器可以通過 setTimeout 設(shè)置,例如。如果設(shè)置為無限大,則循環(huán)將等待傳入連接以進(jìn)行更多工作。這是一個半無限循環(huán),因?yàn)楫?dāng)沒有剩餘工作並且存在活動連接時,輪詢會使循環(huán)保持活動狀態(tài)。

以下是此超時計算的 Unix 版本,以其全部 C 代碼形式:

setTimeout(
  () => console.log('Hi from the callback queue'),
  5000); // 保持循環(huán)活動這么長時間

const stopTime = Date.now() + 2000;
while (Date.now() < stopTime) {}

您可能不太熟悉 C 語言,但這讀起來像英語,並且完全按照第七階段所述執(zhí)行。

逐階段演示

為了用純 JavaScript 顯示每個階段:

const stopTime = Date.now() + 2000;
while (Date.now() < stopTime) {}
// 這需要 7 秒才能執(zhí)行
setTimeout(() => console.log('Ran callback A'), 5000);

因?yàn)槲募?I/O 回調(diào)在階段四和階段九之前運(yùn)行,所以預(yù)計 setImmediate() 會先觸發(fā):

const fs = require('fs');
const readFileSync = async (path) => await fs.readFileSync(path);

readFileSync('readme.md').then((data) => console.log(data));
console.log('The event loop continues without blocking...');

沒有 DNS 查詢的網(wǎng)絡(luò) I/O 比文件 I/O 成本更低,因?yàn)樗谥魇录h(huán)中執(zhí)行。文件 I/O 通過線程池排隊(duì)。 DNS 查詢也使用線程池,因此這使得網(wǎng)絡(luò) I/O 與文件 I/O 一樣昂貴。

線程池

Node.js 內(nèi)部有兩個主要部分:V8 JavaScript 引擎和 libuv。文件 I/O、DNS 查詢和網(wǎng)絡(luò) I/O 通過 libuv 進(jìn)行。

這是整體架構(gòu):

The Node.js Event Loop: A Developer's Guide to Concepts & Code

圖片源:libuv 文檔

對於網(wǎng)絡(luò) I/O,事件循環(huán)在主線程內(nèi)進(jìn)行輪詢。此線程不是線程安全的,因?yàn)樗粫c另一個線程進(jìn)行上下文切換。文件 I/O 和 DNS 查詢是特定於平臺的,因此方法是在線程池中運(yùn)行它們。一個想法是自己進(jìn)行 DNS 查詢以避免進(jìn)入線程池,如上面的代碼所示。例如,輸入 IP 地址而不是 localhost 會將查找從池中移除。線程池中可用的線程數(shù)量有限,可以通過 UV_THREADPOOL_SIZE 環(huán)境變量進(jìn)行設(shè)置。默認(rèn)線程池大小約為四個。

V8 在單獨(dú)的循環(huán)中執(zhí)行,清空調(diào)用棧,然後將控制權(quán)返回給事件循環(huán)。 V8 可以使用多個線程進(jìn)行其自身循環(huán)之外的垃圾回收??梢詫?V8 視為一個引擎,它接收原始 JavaScript 並將其在硬件上運(yùn)行。

對於普通程序員來說,JavaScript 保持單線程,因?yàn)闆]有線程安全問題。 V8 和 libuv 內(nèi)部會啟動它們自己單獨(dú)的線程以滿足它們自己的需求。

如果 Node.js 中存在吞吐量問題,請從主事件循環(huán)開始。檢查應(yīng)用程序完成單個迭代需要多長時間。它不應(yīng)超過一百毫秒。然後,檢查線程池飢餓以及可以從池中驅(qū)逐的內(nèi)容。也可以通過環(huán)境變量增加池的大小。最後一步是在同步執(zhí)行的 V8 中對 JavaScript 代碼進(jìn)行微基準(zhǔn)測試。

總結(jié)

事件循環(huán)繼續(xù)迭代每個階段,因?yàn)榛卣{(diào)被排隊(duì)。但是,在每個階段內(nèi),都有方法可以排隊(duì)另一種類型的回調(diào)。

process.nextTick() 與 setImmediate()

在每個階段結(jié)束時,循環(huán)執(zhí)行 process.nextTick() 回調(diào)。請注意,此回調(diào)類型不是事件循環(huán)的一部分,因?yàn)樗诿總€階段結(jié)束時運(yùn)行。 setImmediate() 回調(diào)是整個事件循環(huán)的一部分,因此它並不像名稱暗示的那樣立即執(zhí)行。由於 process.nextTick() 需要了解事件循環(huán)的內(nèi)部機(jī)制,因此我通常建議使用 setImmediate()。

您可能需要 process.nextTick() 的幾個原因:

  1. 允許網(wǎng)絡(luò) I/O 在循環(huán)繼續(xù)之前處理錯誤、清理或重試請求。
  2. 可能需要在調(diào)用棧展開後但在循環(huán)繼續(xù)之前運(yùn)行回調(diào)。

例如,事件發(fā)射器希望在其自身構(gòu)造函數(shù)中觸發(fā)事件。調(diào)用棧必須先展開才能調(diào)用事件。

setTimeout(
  () => console.log('Hi from the callback queue'),
  5000); // 保持循環(huán)活動這么長時間

const stopTime = Date.now() + 2000;
while (Date.now() < stopTime) {}

允許調(diào)用棧展開可以防止諸如 RangeError: Maximum call stack size exceeded 之類的錯誤。一個需要注意的是確保 process.nextTick() 不會阻塞事件循環(huán)。在同一階段內(nèi)遞歸回調(diào)調(diào)用可能會導(dǎo)致阻塞問題。

結(jié)論

事件循環(huán)在其終極複雜性中體現(xiàn)了簡單性。它解決了一個難題,例如異步性、線程安全性和並發(fā)性。它刪除了無用或不需要的部分,並以最有效的方式最大限度地提高了吞吐量。因此,Node.js 程序員可以減少追逐異步錯誤的時間,而將更多時間用於交付新功能。

關(guān)於 Node.js 事件循環(huán)的常見問題

什麼是 Node.js 事件循環(huán)? Node.js 事件循環(huán)是允許 Node.js 執(zhí)行非阻塞異步操作的核心機(jī)制。它負(fù)責(zé)在單線程事件驅(qū)動環(huán)境中處理 I/O 操作、定時器和回調(diào)。

Node 事件循環(huán)是如何工作的?事件循環(huán)不斷檢查事件隊(duì)列中是否有待處理的事件或回調(diào),並按添加順序執(zhí)行它們。它在一個循環(huán)中運(yùn)行,根據(jù)事件的可用性處理事件,這使得 Node.js 中的異步編程成為可能。

事件循環(huán)在 Node.js 應(yīng)用程序中的作用是什麼?事件循環(huán)是 Node.js 的核心,它確保應(yīng)用程序保持響應(yīng)能力,並且可以處理許多同時連接,而無需多線程。

Node.js 事件循環(huán)的階段有哪些? Node.js 中的事件循環(huán)有幾個階段,包括定時器、待處理回調(diào)、空閒、輪詢、檢查和關(guān)閉。這些階段決定了事件的處理方式和順序。

事件循環(huán)處理的最常見事件類型有哪些?常見的事件包括 I/O 操作(例如,從文件讀取或發(fā)出網(wǎng)絡(luò)請求)、定時器(例如,setTimeout 和 setInterval)和回調(diào)函數(shù)(例如,來自異步操作的回調(diào))。

Node 如何在事件循環(huán)中處理長時間運(yùn)行的操作?長時間運(yùn)行的 CPU 密集型操作可能會阻塞事件循環(huán),應(yīng)使用 child_process 或 worker_threads 模塊等模塊將其卸載到子進(jìn)程或工作線程中。

調(diào)用棧和事件循環(huán)有什麼區(qū)別?調(diào)用棧是一個數(shù)據(jù)結(jié)構(gòu),用於跟蹤當(dāng)前執(zhí)行上下文中的函數(shù)調(diào)用,而事件循環(huán)負(fù)責(zé)管理異步和非阻塞操作。它們協(xié)同工作,因?yàn)槭录h(huán)調(diào)度回調(diào)和 I/O 操作的執(zhí)行,然後將它們推送到調(diào)用棧中。

事件循環(huán)中的“tick”是什麼? “tick”指的是事件循環(huán)的單個迭代。在每次 tick 中,事件循環(huán)都會檢查是否有待處理的事件,並執(zhí)行任何準(zhǔn)備運(yùn)行的回調(diào)。 Ticks 是 Node.js 應(yīng)用程序中的基本工作單元。

以上是Node.js事件循環(huán):開發(fā)人員的概念和代碼指南的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語言,各自適用於不同的應(yīng)用場景。 Java用於大型企業(yè)和移動應(yīng)用開發(fā),而JavaScript主要用於網(wǎng)頁開發(fā)。

JavaScript評論:簡短說明 JavaScript評論:簡短說明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區(qū)問題建議使用支持時區(qū)的庫,如Luxon。掌握這些要點(diǎn)能有效避免常見錯誤。

JavaScript與Java:開發(fā)人員的全面比較 JavaScript與Java:開發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript:探索用於高效編碼的數(shù)據(jù)類型 JavaScript:探索用於高效編碼的數(shù)據(jù)類型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應(yīng)用戶操作的時機(jī)和方式。

Java和JavaScript有什麼區(qū)別? Java和JavaScript有什麼區(qū)別? Jun 17, 2025 am 09:17 AM

Java和JavaScript是不同的編程語言。 1.Java是靜態(tài)類型、編譯型語言,適用於企業(yè)應(yīng)用和大型系統(tǒng)。 2.JavaScript是動態(tài)類型、解釋型語言,主要用於網(wǎng)頁交互和前端開發(fā)。

See all articles