亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
事件循環(huán)如何運(yùn)作
堆疊
隊(duì)列
保持我們的網(wǎng)頁(yè)回應(yīng)
最終想法
首頁(yè) CMS教程 &#&按 解讀JavaScript中的事件循環(huán)

解讀JavaScript中的事件循環(huán)

Sep 03, 2023 pm 01:17 PM
會(huì)放入隊(duì)尾 等待javascript引擎執(zhí)行。 透過事件隊(duì)列

解讀JavaScript中的事件循環(huán)

您可能已經(jīng)知道 JavaScript 是單執(zhí)行緒程式語(yǔ)言。這意味著 JavaScript 在 Web 瀏覽器或 Node.js 中的單一主執(zhí)行緒上運(yùn)行。在單一主執(zhí)行緒上運(yùn)行意味著一次只運(yùn)行一段 JavaScript 程式碼。

JavaScript 中的事件循環(huán)在決定程式碼如何在主執(zhí)行緒上執(zhí)行方面發(fā)揮著重要作用。事件循環(huán)負(fù)責(zé)一些事情,例如程式碼的執(zhí)行以及事件的收集和處理。它也處理任何排隊(duì)子任務(wù)的執(zhí)行。

在本教程中,您將學(xué)習(xí) JavaScript 中事件循環(huán)的基礎(chǔ)知識(shí)。

事件循環(huán)如何運(yùn)作

為了理解事件循環(huán)的工作原理,您需要了解三個(gè)重要術(shù)語(yǔ)。

堆疊

呼叫堆疊只是追蹤函數(shù)執(zhí)行上下文的函數(shù)呼叫堆疊。該堆疊遵循後進(jìn)先出 (LIFO) 原則,這意味著最近調(diào)用的函數(shù)將是第一個(gè)執(zhí)行的函數(shù)。

隊(duì)列

佇列包含一系列由 JavaScript 執(zhí)行的任務(wù)。該佇列中的任務(wù)可能會(huì)導(dǎo)致呼叫函數(shù),然後將其放入堆疊中。僅當(dāng)堆疊為空時(shí)才開始佇列的處理。隊(duì)列中的項(xiàng)目遵循先進(jìn)先出 (FIFO) 原則。這意味著最舊的任務(wù)將首先完成。

堆基本上是儲(chǔ)存和分配物件的一大塊記憶體區(qū)域。它的主要目的是儲(chǔ)存堆疊中的函數(shù)可能使用的資料。

基本上,JavaScript 是單執(zhí)行緒的,一次執(zhí)行一個(gè)函數(shù)。這個(gè)單一函數(shù)被放置在堆疊上。該函數(shù)還可以包含其他巢狀函數(shù),這些函數(shù)將放置在堆疊中的上方。堆疊遵循 LIFO 原則,因此最近呼叫的巢狀函數(shù)將首先執(zhí)行。

API 請(qǐng)求或計(jì)時(shí)器等非同步任務(wù)將會(huì)新增至佇列以便稍後執(zhí)行。 JavaScript 引擎在空閒時(shí)開始執(zhí)行佇列中的任務(wù)。

考慮以下範(fàn)例:

function helloWorld() {
    console.log("Hello, World!");
}

function helloPerson(name) {
    console.log(`Hello, ${name}!`);
}

function helloTeam() {
    console.log("Hello, Team!");
    helloPerson("Monty");
}

function byeWorld() {
    console.log("Bye, World!");
}

helloWorld();
helloTeam();
byeWorld();

/* Outputs:

Hello, World!
Hello, Team!
Hello, Monty!
Bye, World!

*/

讓我們看看如果運(yùn)行上面的程式碼,堆疊和佇列會(huì)是什麼樣子。

呼叫 helloWorld() 函數(shù)並將其放入堆疊中。它記錄 Hello, World! 完成其執(zhí)行,因此它被從堆疊中取出。接下來呼叫 helloTeam() 函數(shù)並將其放入堆疊中。在執(zhí)行過程中,我們記錄 Hello, Team! 並呼叫 helloPerson()。 helloTeam() 的執(zhí)行還沒完成,所以它停留在堆疊上,而 helloPerson() 則放在它上面。

後進(jìn)先出原則規(guī)定 helloPerson() 現(xiàn)在執(zhí)行。這會(huì)將 Hello, Monty! 記錄到控制臺(tái),從而完成其執(zhí)行,並且 helloPerson() 將從堆疊中取出。之後 helloTeam() 函數(shù)就會(huì)出棧,我們最後到達(dá) byeWorld()。它會(huì)記錄再見,世界! ,然後從堆疊中消失。

隊(duì)列一直是空的。

現(xiàn)在,考慮上述程式碼的細(xì)微變化:

function helloWorld() {
    console.log("Hello, World!");
}

function helloPerson(name) {
    console.log(`Hello, ${name}!`);
}

function helloTeam() {
    console.log("Hello, Team!");
    setTimeout(() => {
        helloPerson("Monty");
    }, 0);
}

function byeWorld() {
    console.log("Bye, World!");
}

helloWorld();
helloTeam();
byeWorld();

/* Outputs:

Hello, World!
Hello, Team!
Bye, World!
Hello, Monty!

*/

我們?cè)谶@裡所做的唯一更改是使用 setTimeout()。但是,超時(shí)已設(shè)定為零。因此,我們期望 Hello, Monty!Bye, World! 之前輸出。如果您了解事件循環(huán)的工作原理,您就會(huì)明白為什麼不會(huì)發(fā)生這種情況。 < /p>

當(dāng)helloTeam()入堆疊時(shí),遇到setTimeout()方法。但是,setTimeout() 中對(duì) helloPerson() 的呼叫會(huì)被放入佇列中,一旦沒有同步任務(wù)需要執(zhí)行,就會(huì)被執(zhí)行。

一旦對(duì) byeWorld() 的呼叫完成,事件循環(huán)將檢查佇列中是否有任何掛起的任務(wù),並找到對(duì) helloPerson() 的呼叫。此時(shí),它執(zhí)行該函數(shù)並將 Hello, Monty! 記錄到控制臺(tái)。

這表示您提供給 setTimeout() 的超時(shí)持續(xù)時(shí)間並不是回呼執(zhí)行的保證時(shí)間。這是執(zhí)行回調(diào)的最短時(shí)間。

保持我們的網(wǎng)頁(yè)回應(yīng)

JavaScript 的一個(gè)有趣的功能是它會(huì)執(zhí)行一個(gè)函數(shù)直到完成。這意味著只要函數(shù)在堆疊上,事件循環(huán)就無(wú)法處理佇列中的任何其他任務(wù)或執(zhí)行其他函數(shù)。

這可能會(huì)導(dǎo)致網(wǎng)頁(yè)“掛起”,因?yàn)樗鼰o(wú)法執(zhí)行其他操作,例如處理使用者輸入或進(jìn)行與 DOM 相關(guān)的更改。考慮以下範(fàn)例,我們?cè)谄渲胁檎医o定範(fàn)圍內(nèi)的素?cái)?shù)數(shù)量:

function isPrime(num) {
  if (num <= 1) {
    return false;
  }

  for (let i = 2; i <= Math.sqrt(num); i++) {
    if (num % i === 0) {
      return false;
    }
  }
  
  return true;
}

function listPrimesInRange(start, end) {
  const primes = [];

  for (let num = start; num <= end; num++) {
    if (isPrime(num)) {
      primes.push(num);
    }
  }

  return primes;
}

在我們的 listPrimesInRange() 函數(shù)中,我們迭代從 startend 的數(shù)字。對(duì)於每個(gè)數(shù)字,我們呼叫 isPrime() 函數(shù)來查看它是否是質(zhì)數(shù)。 isPrime() 函數(shù)本身有一個(gè)for 循環(huán),從2Math.sqrt(num) 來決定數(shù)字是否為素?cái)?shù)。

查找給定范圍內(nèi)的所有素?cái)?shù)可能需要一段時(shí)間,具體取決于您使用的值。當(dāng)瀏覽器進(jìn)行此計(jì)算時(shí),它無(wú)法執(zhí)行任何其他操作。這是因?yàn)?listPrimesInRange() 函數(shù)將保留在堆棧中,瀏覽器將無(wú)法執(zhí)行隊(duì)列中的任何其他任務(wù)。

現(xiàn)在,看一下以下函數(shù):

function listPrimesInRangeResponsively(start) {
  let next = start + 100,000;

  if (next > end) {
    next = end;
  }

  for (let num = start; num <= next; num++) {
    if (isPrime(num)) {
      primeNumbers.push(num);
    }

    if (num == next) {
      percentage = ((num - begin) * 100) / (end - begin);
      percentage = Math.floor(percentage);

      progress.innerText = `Progress ${percentage}%`;

      if (num != end) {
        setTimeout(() => {
          listPrimesInRangeResponsively(next + 1);
        });
      }
    }

    if (num == end) {
      percentage = ((num - begin) * 100) / (end - begin);
      percentage = Math.floor(percentage);

      progress.innerText = `Progress ${percentage}%`;

      heading.innerText = `${primeNumbers.length - 1} Primes Found!`;

      console.log(primeNumbers);

      return primeNumbers;
    }
  }
}

這一次,我們的函數(shù)僅在批量處理范圍時(shí)嘗試查找素?cái)?shù)。它通過遍歷所有數(shù)字但一次僅處理其中的 100,000 個(gè)來實(shí)現(xiàn)這一點(diǎn)。之后,它使用 setTimeout() 觸發(fā)對(duì)同一函數(shù)的下一次調(diào)用。

當(dāng) setTimeout() 被調(diào)用而沒有指定延遲時(shí),它會(huì)立即將回調(diào)函數(shù)添加到事件隊(duì)列中。

下一個(gè)調(diào)用將被放入隊(duì)列中,暫時(shí)清空堆棧以處理任何其他任務(wù)。之后,JavaScript 引擎開始在下一批 100,000 個(gè)數(shù)字中查找素?cái)?shù)。

嘗試單擊此頁(yè)面上的計(jì)算(卡?。?/strong>按鈕,您可能會(huì)收到一條消息,指出該網(wǎng)頁(yè)正在減慢您的瀏覽器速度,并建議您停止該腳本。 p>

另一方面,單擊計(jì)算(響應(yīng)式)按鈕仍將使網(wǎng)頁(yè)保持響應(yīng)式。

最終想法

在本教程中,我們了解了 JavaScript 中的事件循環(huán)以及它如何有效地執(zhí)行同步和異步代碼。事件循環(huán)使用隊(duì)列來跟蹤它必須執(zhí)行的任務(wù)。

由于 JavaScript 不斷執(zhí)行函數(shù)直至完成,因此進(jìn)行大量計(jì)算有時(shí)會(huì)“掛起”瀏覽器窗口。根據(jù)我們對(duì)事件循環(huán)的理解,我們可以重寫我們的函數(shù),以便它們批量進(jìn)行計(jì)算。這允許瀏覽器保持窗口對(duì)用戶的響應(yīng)。它還使我們能夠定期向用戶更新我們?cè)谟?jì)算中取得的進(jìn)展。

以上是解讀JavaScript中的事件循環(huán)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

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

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(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)頁(yè)開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
如何診斷WordPress引起的高CPU使用 如何診斷WordPress引起的高CPU使用 Jul 06, 2025 am 12:08 AM

WordPress導(dǎo)致服務(wù)器CPU使用率飆升的主要原因包括插件問題、數(shù)據(jù)庫(kù)查詢效率低、主題代碼質(zhì)量差或流量激增。 1.首先通過top、htop或控制面板工具確認(rèn)是否為WordPress引起的高負(fù)載;2.進(jìn)入故障排查模式逐步啟用插件排查性能瓶頸,使用QueryMonitor分析插件執(zhí)行情況並刪除或替換低效插件;3.安裝緩存插件、清理冗餘數(shù)據(jù)、分析慢查詢?nèi)照I以優(yōu)化數(shù)據(jù)庫(kù);4.檢查主題是否存在過度加載內(nèi)容、複雜查詢或缺乏緩存機(jī)制等問題,建議用標(biāo)準(zhǔn)主題測(cè)試對(duì)比並優(yōu)化代碼邏輯。按照上述步驟逐一排查可定位並解

如何在WordPress中縮小JavaScript文件 如何在WordPress中縮小JavaScript文件 Jul 07, 2025 am 01:11 AM

MinifyingJavaScript文件可通過刪除空白、註釋和無(wú)用代碼來提升WordPress網(wǎng)站加載速度。 1.使用支持合併壓縮的緩存插件如W3TotalCache,在“Minify”選項(xiàng)中啟用並選擇壓縮模式;2.使用專用壓縮插件如FastVelocityMinify,提供更精細(xì)控制;3.手動(dòng)壓縮JS文件並通過FTP上傳,適用於熟悉開發(fā)工具的用戶。注意部分主題或插件腳本可能與壓縮功能衝突,啟用後需徹底測(cè)試網(wǎng)站功能。

如何在沒有插件的情況下優(yōu)化WordPress 如何在沒有插件的情況下優(yōu)化WordPress Jul 05, 2025 am 12:01 AM

優(yōu)化WordPress站點(diǎn)不依賴插件的方法包括:1.使用輕量級(jí)主題,如Astra或GeneratePress,避免功能堆砌的主題;2.手動(dòng)壓縮和合併CSS、JS文件,減少HTTP請(qǐng)求;3.上傳前優(yōu)化圖片,使用WebP格式並控製文件大小;4.配置.htaccess啟用瀏覽器緩存,並接入CDN提升靜態(tài)資源加載速度;5.限製文章修訂版本並定期清理數(shù)據(jù)庫(kù)冗餘數(shù)據(jù)。

如何以編程方式防止評(píng)論垃圾郵件 如何以編程方式防止評(píng)論垃圾郵件 Jul 08, 2025 am 12:04 AM

防止評(píng)論垃圾信息最有效的方式是通過程序化手段自動(dòng)識(shí)別並攔截。 1.使用驗(yàn)證碼機(jī)制(如GooglereCAPTCHA或hCaptcha)可有效區(qū)分人類與機(jī)器人,尤其適合公眾網(wǎng)站;2.設(shè)置隱藏字段(Honeypot技術(shù)),利用機(jī)器人自動(dòng)填寫特性識(shí)別垃圾評(píng)論,不影響用戶體驗(yàn);3.檢查評(píng)論內(nèi)容關(guān)鍵詞黑名單,通過敏感詞匹配過濾垃圾信息,需注意避免誤判;4.判斷評(píng)論頻率與來源IP,限制單位時(shí)間內(nèi)的提交次數(shù)並建立黑名單;5.使用第三方反垃圾服務(wù)(如Akismet、Cloudflare)提升識(shí)別準(zhǔn)確性??筛鶕?jù)網(wǎng)站

如何使用瞬態(tài)API進(jìn)行緩存 如何使用瞬態(tài)API進(jìn)行緩存 Jul 05, 2025 am 12:05 AM

TransientsAPI是WordPress中用於臨時(shí)存儲(chǔ)可自動(dòng)過期數(shù)據(jù)的內(nèi)置工具,其核心函數(shù)為set_transient、get_transient和delete_transient。相比OptionsAPI,transients支持設(shè)置生存時(shí)間(TTL),適合緩存API請(qǐng)求結(jié)果、複雜計(jì)算數(shù)據(jù)等場(chǎng)景。使用時(shí)需注意key命名唯一性與命名空間、緩存“懶刪除”機(jī)制及對(duì)象緩存環(huán)境下可能不持久的問題。典型應(yīng)用場(chǎng)景包括減少外部請(qǐng)求頻率、控制代碼執(zhí)行節(jié)奏和提升頁(yè)面加載性能。

如何爭(zhēng)取古騰堡大塊的資產(chǎn) 如何爭(zhēng)取古騰堡大塊的資產(chǎn) Jul 09, 2025 am 12:14 AM

在開發(fā)Gutenberg塊時(shí),正確enqueue資產(chǎn)的方法包括:1.使用register_block_type指定editor_script、editor_style和style的路徑;2.在functions.php或插件中通過wp_register_script和wp_register_style註冊(cè)資源,並設(shè)置正確的依賴和版本;3.配置構(gòu)建工具輸出合適的模塊格式,並確保路徑一致;4.通過add_theme_support或enqueue_block_assets控制前端樣式的加載邏輯,確保

如何向用戶添加自定義字段 如何向用戶添加自定義字段 Jul 06, 2025 am 12:18 AM

要添加自定義用戶字段需根據(jù)平臺(tái)選擇擴(kuò)展方式並註意數(shù)據(jù)驗(yàn)證與權(quán)限控制。常見做法包括:1.利用數(shù)據(jù)庫(kù)額外表或鍵值對(duì)結(jié)構(gòu)存儲(chǔ)信息;2.在前端加入輸入框並與後端集成;3.對(duì)敏感數(shù)據(jù)進(jìn)行格式校驗(yàn)和訪問權(quán)限限制;4.更新接口及模板以支持新字段展示與編輯,同時(shí)兼顧移動(dòng)端適配和用戶體驗(yàn)。

如何添加自定義重寫規(guī)則 如何添加自定義重寫規(guī)則 Jul 08, 2025 am 12:11 AM

在WordPress中添加自定義重寫規(guī)則的關(guān)鍵在於使用add_rewrite_rule函數(shù)並確保規(guī)則正確生效。 1.使用add_rewrite_rule註冊(cè)規(guī)則,格式為add_rewrite_rule($regex,$redirect,$after),其中$regex是正則表達(dá)式匹配URL,$redirect指定實(shí)際查詢,$after控制規(guī)則位置;2.需通過add_filter添加自定義查詢變量;3.修改後必須刷新固定鏈接設(shè)置;4.建議將規(guī)則放在'top'以避免衝突;5.可藉助插件查看當(dāng)前規(guī)則便於

See all articles