偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

給女朋友講了講 V8 引擎的“回調(diào)函數(shù)”!

開發(fā) 前端
今天主要和大家分享了 JavaScript 中回調(diào)函數(shù)的由來和異步回調(diào)函數(shù)的設(shè)計,這也是 V8 引擎中的一小部分

回調(diào)函數(shù)相信大家并不陌生,但是對于女朋友來說比較陌生,要想給女朋友講明白回調(diào)函數(shù)是怎么回事,為什么要這樣設(shè)計,使用回調(diào)函數(shù)應該注意什么,確實不容易,所以有了這篇文章。

在 JavaScript 中,我個人覺得理解回調(diào)函數(shù),就有助于我們理解 JavaScript 中的其它設(shè)計,比如異步編程、消息循環(huán)、一些常用到的 Web API 以及 Node 中的異步,這些都與回調(diào)函數(shù)息息相關(guān),所以咱們一步步的來學習和使用。

廢話不多說,直接上干貨!

[[348215]]

什么是回調(diào)函數(shù)?

回調(diào)函數(shù)也是函數(shù)的一種,回調(diào)函數(shù)與普通函數(shù)的區(qū)別在于它的調(diào)用時機。所謂的回調(diào)函數(shù)是把一個函數(shù)當作另一個函數(shù)的參數(shù),并在這個函數(shù)的某個時機進行調(diào)用,我們就將這個傳入的函數(shù)稱為回調(diào)函數(shù)。

回調(diào)函數(shù)分為同步回調(diào)和異步回調(diào)。它倆的區(qū)別在于調(diào)用的位置不同。

1. 同步回調(diào)

所謂的同步回調(diào)函數(shù)是在執(zhí)行的函數(shù)內(nèi)部被調(diào)用的。舉個例子:

  1. function fn(){ 
  2.     console.log("我是同步回調(diào)函數(shù)"); 
  3.  
  4. function bar(f){ 
  5.      f(); 
  6.  
  7. bar(fn); 

我們聲明了一個回調(diào)函數(shù) fn,我們傳入 bar 函數(shù),我們在 bar 內(nèi)部調(diào)用了 fn,此時就是同步調(diào)用。

2. 異步回調(diào)

而異步回調(diào)函數(shù)是在執(zhí)行的函數(shù)外部被調(diào)用的。如下代碼:

  1. function fn(){ 
  2.     console.log("我是異步回調(diào)函數(shù)"); 
  3.  
  4. settimeout(fn, 1000); 

上述代碼中,settimeout 的第一個參數(shù) fn 是傳入的一個回調(diào)函數(shù),當程序執(zhí)行 1000 ms 的時候,此時這個回調(diào)函數(shù)被調(diào)用,而且是在 setTimeout 函數(shù)外部被調(diào)用的,我們稱 fn 為異步回調(diào)函數(shù)。

JS 線程架構(gòu)

上述的問題理解起來非常簡單,尤其是同步回調(diào)函數(shù)。但是對于異步回調(diào)函數(shù)什么時候被調(diào)用的,是在什么位置被調(diào)用的,我們目前是非常模糊的。

所以要想知道異步回調(diào)函數(shù)的調(diào)用時機和位置,我們需要理解 JS 的線程架構(gòu),比如消息隊列、事件循環(huán),從根上理解 JS 是如何設(shè)計這些東西的。

JS 的最初設(shè)計是單線程的,所謂的單線程就是同一時間只能干一件事情,而且 JS 運行的這個單線程就是頁面的 UI 線程,畢竟 JS 為了能夠更方便的操作 DOM 嘛。

那么問題來了,當我們把 JS 設(shè)計到 UI 頁面線程,就會出現(xiàn)一個問題,當用戶通過頁面交互產(chǎn)生一個事件時,如果當前的線程正在處理其他的任務,那么這個交互事件需要等當前 UI 線程的任務處理完畢才能被處理,所以這樣設(shè)計比較雞肋。

如果當前 UI 線程一直執(zhí)行其他任務,那么這個用戶的交互事件任務一直不被處理,會出現(xiàn)頁面點擊無效的假象。

谷歌 V8 團隊為了解決這個問題,那么就引入了消息隊列。

消息隊列

有了消息隊列,我們把所有產(chǎn)生的事件,無論是 JavaScript 產(chǎn)生的事件還是用戶點擊頁面交互產(chǎn)生的事件,都統(tǒng)一按照先后循序放到消息隊列中,那么 UI 線程就不斷的循環(huán)這個消息隊列,有任務就取出來去執(zhí)行。

有了消息隊列之后,這個主線程就可以有序的執(zhí)行各種事件任務了。

異步任務什么時候調(diào)用?

還是上述的 setTimeout 異步回調(diào)函數(shù)的例子,假如當前線程在消息隊列中取出 setTimeout 這段代碼執(zhí)行,發(fā)現(xiàn) fn 這個任務是在 1000 ms 后執(zhí)行的,1000 ms 過后,主線程就會將 fn 封裝成一個事件任務扔到消息隊列中去等待被執(zhí)行。

等消息隊列中的執(zhí)行到一定的時機,就會取出這個被封裝過的 fn 回調(diào)函數(shù)任務,在主線程中被執(zhí)行。

這個理解起來并不是很難,但是有一類回調(diào)函數(shù)比較特殊。當主線程在消息隊列中取出一個網(wǎng)絡下載的任務時,網(wǎng)絡下載比較耗時,我們不可能讓它在主線程中阻塞其他任務執(zhí)行,所以主線程就會交給網(wǎng)絡線程去執(zhí)行這個下載任務,然后主線程回繼續(xù)有序的在消息隊列中取出其他任務執(zhí)行。

此時網(wǎng)絡線程會接受到這個任務執(zhí)行下載操作,當網(wǎng)絡線程把文件下載完畢之后,就將下載的結(jié)果封裝成一個事件任務,放入到消息隊列中。當主線程執(zhí)行到這個任務時,就知道網(wǎng)絡線程已經(jīng)下載完了,然后將下載的結(jié)果呈現(xiàn)給用戶。

最后

好了,今天主要和大家分享了 JavaScript 中回調(diào)函數(shù)的由來和異步回調(diào)函數(shù)的設(shè)計,這也是 V8 引擎中的一小部分,接下來會通過這樣一個個的知識點,挖掘 V8 谷歌引擎的各個方面的優(yōu)秀設(shè)計方案。

 

責任編輯:趙寧寧 來源: 小鹿動畫學編程
相關(guān)推薦

2021-06-22 07:45:57

React18startTransiReact

2021-06-22 07:30:07

React18Automatic b自動批處理

2022-10-24 09:11:05

TypeScriptV8

2022-06-02 12:02:12

V8C++JavaScript

2021-10-21 08:31:31

Spring循環(huán)依賴面試

2019-03-12 09:43:14

反向代理正向代理服務器

2021-03-05 17:06:53

全排列組合子集

2020-03-16 14:08:59

線程熔斷限流

2019-04-09 09:40:23

2025-09-08 01:55:00

2023-10-10 10:23:50

JavaScriptV8

2019-10-09 10:45:16

云計算Web互聯(lián)網(wǎng)

2021-09-14 12:00:11

VR字節(jié)跳動

2009-07-20 09:36:04

谷歌瀏覽器安全漏洞

2009-08-21 10:09:02

Google ChroV8引擎linux系統(tǒng)

2010-07-20 16:35:52

V8JavaScript瀏覽器

2023-06-07 16:00:40

JavaScriptV8語言

2021-03-09 12:27:05

微服務 微服務架構(gòu)應用程序

2012-02-01 10:33:59

Java

2019-11-28 10:53:19

程序員技能開發(fā)者
點贊
收藏

51CTO技術(shù)棧公眾號