首頁 web前端 js教程 關於js中的同步和非同步的理解

關於js中的同步和非同步的理解

Apr 09, 2018 am 11:19 AM
javascript 同步 非同步

本篇文章給大家分享的內容是關於js中的同步和異步的理解,有著一定的參考價值,有需要的朋友可以參考一下

你應該知道,javascript語言是一門「單線程」的語言,不像java語言,類別繼承Thread再來個thread.start就可以開闢一個線程,所以,javascript就像一條管線,只是一條流水線而已,要嘛加工,要嘛包裝,不能同時進行多個任務和流程。

那麼這裡說的同步異步到底是什麼呢?如果你真的不懂,我希望你認真讀完這篇文章。其實我個人覺得js官方的文件在使用兩個字的時候並不準確,包含很多其他詞彙,都只是聽起來高深,但實際應用好像跟這些字沒半毛錢關係。例如「事件委託」這個詞,不知道的人乍看誰又能說出「事件委託」是什麼意思?委託什麼事件?怎麼個委託,我看不如乾脆就叫“事件在外層元素中的捕獲”,雖然長一點,一下就能看懂。

回歸正軌,「同步」——一下就讓人想到「一起」這個詞;「異步」呢,從字面來講,好像是在不同的(異)的ways上do something,那首先想到的詞可能是“一邊...一邊...”,比如'小明一邊吃雪糕一邊寫作業',這完全沒毛病,雪糕吃完了,作業也寫完了,這就是異步?那就大錯特錯了!

其實同步且非同步,無論如何,做事情的時候都是只有一條管線(單執行緒),同步與非同步的差別就在於這條管線上各個流程的執行順序不同

最基礎的非同步是setTimeout和setInterval函數,很常見,但很少人知道其實這就是非同步,因為它們可以控制js的執行順序。我們也可以簡單地理解為:可以改變程式正常執行順序的操作就可以看成是非同步操作。如下程式碼:

<script type="text/javascript">
        console.log( "1" );
        setTimeout(function() {
            console.log( "2" )
        }, 0 );
        setTimeout(function() {
            console.log( "3" )
        }, 0 );
        setTimeout(function() {
            console.log( "4" )
        }, 0 );
        console.log( "5" );
</script>
登入後複製

輸出順序是什麼呢?

可見,儘管我們設定了setTimeout(function,time)中的等待時間為0,結果其中的function還是後執行。

火狐瀏覽器的api文件有這樣一句話:Because even though setTimeout was called with a delay of zero, it's placed on a queue and scheduled to run at the next opportunity, not immediately. Currently executing code must complete before functions on the queue are executed, the resplete before functions.

意思是:儘管setTimeout的time延遲時間為0,其中的function也會被放入一個佇列中,等待

下一個機會執行,目前的程式碼(指不需要加入佇列中的程式)必須在該佇列的程式完成之前完成,因此結果可能不與預期結果相同。

這裡說到了一個「佇列」(即任務佇列),該佇列放的是什麼呢,放的就是setTimeout中的function,這些function依序加入該佇列,即該佇列中所有function中的程式將會在該佇列以外的所有程式碼執行完畢之後再以此執行,這是為什麼呢?因為在執行程式的時候,瀏覽器會預設setTimeout以及ajax請求這一類的方法都是耗時程式(儘管可能不耗時),將其加入一個佇列中,該佇列是一個儲存耗時程式的佇列,在所有不耗時程式執行過後,再來依序執行該佇列中的程式。

又回到了最初的起點-javascript是單執行緒。單線程就意味著,所有任務都需要排隊,前一個任務結束,才會執行後一個任務。如果前一個任務耗時很長,後一個任務就得一直等著。於是就有一個概念──任務隊列。如果排隊是因為運算量大,CPU忙不過來,倒也算了,但是很多時候CPU是閒著的,因為IO設備(輸入輸出設備)很慢(例如Ajax操作從網路讀取資料),不得不等著結果出來,再往下執行。於是JavaScript語言的設計者意識到,這時主執行緒完全可以不管IO設備,掛起處於等待中的任務,先執行排在後面的任務。等到IO設備回傳了結果,再回過頭,把掛起的任務繼續執行下去。

於是,所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是,在主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能執行後一個任務;非同步任務指的是,不進入主執行緒、而進入"任務佇列"(task queue)的任務,只有等主線程任務執行完畢,"任務隊列"開始通知主線程,請求執行任務,該任務才會進入主線程執行。

具體來說,非同步運行機制如下:

(1)所有同步任務都在主執行緒上執行,形成一個執行堆疊(execution context stack)。
(2)主執行緒之外,還存在一個"任務佇列"(task queue)。只要非同步任務有了運行結果,就在"任務隊列"之中放置一個事件。
(3)一旦"執行堆疊"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。
(4)主執行緒不斷重複上面的第三步。

只要主執行緒空了,就會去讀取"任務佇列",這就是JavaScript的運作機制。這個過程會不斷重複。

"任務佇列"是一個事件的佇列(也可以理解成訊息的佇列),IO裝置完成一項任務,就在"任務佇列"中新增一個事件,表示相關的非同步任務可以進入"執行棧"了。主執行緒讀取"任務佇列",就是讀取裡面有哪些事件。
"任務佇列"中的事件,除了IO設備的事件以外,還包括一些使用者產生的事件(例如滑鼠點擊、頁面滾動等等),例如$(selectot).click(function),這些都是相對耗時的操作。只要指定過這些事件的回呼函數,這些事件發生時就會進入"任務佇列",等待主執行緒讀取。
所謂"回呼函數"(callback),就是那些會被主執行緒掛起來的程式碼,前面說的點擊事件$(selectot).click(function)中的function就是一個回呼函數。非同步任務必須指定回呼函數,當主執行緒開始執行非同步任務,就是執行對應的回呼函數。例如ajax的success,complete,error也都指定了各自的回呼函數,這些函數就會加入「任務佇列」中,等待執行。

相關推薦:

#js同步與非同步

JavaScript同步、非同步、回呼執行順序分析

#深入了解JavaScript程式設計中的同步與非同步機制

以上是關於js中的同步和非同步的理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

解決win11同時播放耳機與音響的問題 解決win11同時播放耳機與音響的問題 Jan 06, 2024 am 08:50 AM

一般來說,我們只需要同時使用耳機或音響的其中一個設備,但是有些朋友反映在win11系統中,遇到了耳機和音響一起響的問題,其實我們可以在realtek面板中將它關閉,就可以了,下面一起來看一下吧。 win11耳機和音響一起響怎麼辦1、先在桌面上找到並打開“控制面板”2、進入控制面板,在其中找到並打開“硬體和聲音”3、然後再找到一個喇叭圖標的“Realtek高清晰音訊管理器”4、選擇“揚聲器”再點擊“後面板”進入揚聲器設定。 5.打開之後我們可以看到設備類型,如果要關閉耳機就取消勾選“耳機”,如果要

您同步的資料夾中的一個或多個項目不符合Outlook錯誤 您同步的資料夾中的一個或多個項目不符合Outlook錯誤 Mar 18, 2024 am 09:46 AM

當您在您的同步資料夾中發現一個或多個項目與Outlook中的錯誤訊息不符時,這可能是因為您更新或取消了會議項目。在這種情況下,您會看到一條錯誤訊息,提示您的本機資料版本與遠端副本有衝突。這種情況通常發生在Outlook桌面應用程式中。您同步的資料夾中的一個或多個項目不符。若要解決衝突,請開啟這些項目,然後重試此操作。修復同步的資料夾中的一個或多個項目不符合Outlook錯誤在Outlook桌面版中,當本機行事曆項目與伺服器副本發生衝突時,可能會遇到問題。不過,幸運的是,有一些簡單的方法可以幫助您

教你如何將win10剪貼簿與手機同步 教你如何將win10剪貼簿與手機同步 Jan 06, 2024 am 09:18 AM

win10剪貼簿有個非常好用的功能就是跨裝置雲端儲存功能,非常的好用可以幫助用戶PC設備和手機設備同步複製貼上。設定的方法非常簡單,只要在系統裡的剪切板設置就好。 win10剪貼簿同步到手機1、先點選左下角的開始,進入設定。 2、然後去點選「系統」。 3.選擇左側的「剪貼簿」。 4.最後在右邊的「跨裝置同步」點選登錄,然後選擇手機就好了。

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Python asyncio 進階指南:從初學者到專家 Python asyncio 進階指南:從初學者到專家 Mar 04, 2024 am 09:43 AM

並發和非同步編程並發編程處理同時執行的多個任務,非同步編程是一種並發編程,其中任務不會阻塞線程。 asyncio是python中用於非同步程式設計的函式庫,它允許程式在不阻塞主執行緒的情況下執行I/O操作。事件循環asyncio的核心是事件循環,它監控I/O事件並調度相應的任務。當一個協程準備好時,事件循環會執行它,直到它等待I/O操作。然後,它會暫停協程並繼續執行其他協程。協程協程是可暫停和恢復執行的函數。 asyncdef關鍵字用於建立協程。協程使用await關鍵字等待I/O作業完成。 asyncio的基礎以下

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

百度雲端同步盤怎麼同步 百度雲端同步盤怎麼同步 Feb 23, 2024 pm 01:22 PM

百度雲同步盤怎麼同步?百度雲同步盤中可以選擇文件來同步,但是多數的用戶不知道如何同步百度雲文件,接下來就是小編為用戶帶來的百度云同步盤同步方法圖文教程,有興趣的用戶快來一起看看吧!百度雲同步盤怎麼同步1、先進入電腦桌面,右鍵點選【百度雲同步盤】圖標,選擇【設定】;2、之後展開服務小窗口,切換到【進階設定】頁面點選【選擇資料夾】; 3.最後切換到下圖的頁面,勾選需要同步的檔案點選【確定】即可。

Python 並發程式設計中的鎖與同步:保持你的程式碼安全可靠 Python 並發程式設計中的鎖與同步:保持你的程式碼安全可靠 Feb 19, 2024 pm 02:30 PM

並發程式設計中的鎖定與同步在並發程式設計中,多個行程或執行緒同時執行,這可能會導致資源爭用和不一致性問題。為了解決這些問題,需要使用鎖定和同步機制來協調對共享資源的存取。鎖的概念鎖是一種機制,它允許一次只有一個執行緒或程序存取共享資源。當一個執行緒或程序獲得鎖時,其他執行緒或程序將被阻止存取該資源,直到鎖被釋放。鎖的類型python中有幾種類型的鎖:互斥鎖(Mutex):確保一次只有一個執行緒或程序可以存取資源。條件變數:允許執行緒或行程等待某個條件,然後取得鎖定。讀寫鎖:允許多個執行緒同時讀取資源,但只允許一個執行緒寫入資

See all articles