js中的同步和非同步

2022-09-20 13:24:16 字數 2334 閱讀 4012

一、單執行緒

j**ascript 語言的一大特點就是單執行緒,也就是說,同乙個時間只能做一件事,需要排隊執行。如果前面的a任務會花費大量的時間,就會導致後面的b任務停止執行,知道a執行完才會執行b。如果排隊是因為計算量大,cpu忙不過來,倒也算了,但是很多時候cpu是閒著的,因為io裝置(輸入輸出裝置)很慢(比如ajax操作從網路讀取資料,進行大量計算),不得不等著結果出來,再往下執行。

console.log(date.now());

console.log('**********=');

console.log(date.now());

for (let i = 0; i < 100000000; i++)

console.log('*****');

console.log(date.now());

//輸出

1644333664879

**********=

1644333664879

*****

1644333664922

前兩個時間戳因為**執行很快輸出的時間戳相同,相隔乙個for迴圈後,第三個時間戳輸出與前兩個相差較大相差43毫秒。

這個時候j**ascript語言的設計者意識到,這時主線程完全可以不管io裝置,掛起處於等待中的任務,先執行排在後面的任務。等到io裝置返回了結果,再回過頭,把掛起的任務繼續執行下去。

二、同步和非同步

為了防止主線程的不阻塞,非同步方案產生。 所有任務可以分成兩種,一種是同步任務(synchronous),另一種是非同步任務(asynchronous)。同步任務指的是:在主線程上排隊執行的任務,只有前乙個任務執行完畢,才能執行後乙個任務;非同步任務指的是:不進入主線程、而進入"任務佇列"(task queue)的任務,只有"任務佇列"通知主線程,某個非同步任務可以執行了,該任務才會進入主線程執行。任務佇列其實是乙個先進先出的資料結構

(1)所有同步任務都在主線程上執行,形成乙個執行棧(execution context stack)。

(2)主線程之外,還存在乙個"任務佇列"(task queue)。只要非同步任務有了執行結果,就在"任務佇列"之中放置乙個事件。

(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件。那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行。

(4)主線程不斷重複上面的第三步。

console.log(date.now());

console.log('**********=');

console.log(date.now());

settimeout(() =>

console.log('非同步2s');

console.log(date.now());

}, 2000)

settimeout(() =>

console.log('非同步1s');

console.log(date.now());

}, 1000)

console.log('*****');

console.log(date.now());

//輸出

1644334680961

**********=

1644334680961

*****

1644334680961

非同步1s

1644334682005

非同步2s

1644334683012

用定時器(非同步操作)將for迴圈包裹起來,使for迴圈成為非同步操作,不進入主線程。進入佇列任務開始執行。使三個時間戳的輸出相近,不會因為for迴圈而等待大量時間。

非同步1s輸出的時間戳和前乙個同步時間戳相差1044毫秒(減去for迴圈的43毫秒可看作1000毫秒了),非同步2s和非同步1s相差1007毫秒。

意味著非同步任務一進入佇列任務就開始執行,執行完成後會在任務佇列放置乙個結果的事件。當同步認證執行完成後,會進入任務佇列讀取已經執行完成的非同步任務的**函式結果並輸出。

單執行緒從從任務佇列中讀取任務是不斷迴圈的,每次棧被清空後,都會在任務佇列中讀取新的任務,如果沒有任務,就會等到,直到有新的任務,這就叫做任務迴圈,因為每個任務都是由乙個事件觸發的,因此也叫作事件迴圈

三、非同步**函式的理解

普通函式是從上到下執行的,而非同步函式你是不知道他在什麼時候會執行完,但是你有想在他執行完的時候處理結果怎麼辦?使用**函式,非同步任務的**函式會在這個非同步任務執行完的時候進行呼叫,進行處理非同步任務的資料。

所以說普遍的非同步任務都會有乙個**函式,進行資料的處理。

JS中的同步與非同步

一 js中同步非同步程式設計 瀏覽器是多執行緒,js是單執行緒的 瀏覽器只分配乙個執行緒來執行js 程序大執行緒小 乙個程序中包含多個執行緒,例如在瀏覽器中開啟乙個html頁面就占用了乙個程序,載入頁面的時候,瀏覽器分配乙個執行緒去計算dom樹,分配其他的執行緒去載入 對應的資源檔案。在分配乙個執行...

同步非同步通訊和程式編寫中的同步非同步

如果應用程式在執行期間只需要乙個執行緒,請使用下面的方法,這些方法適用於同步操作模式。若要在執行過程中使用單獨的執行緒處理通訊,請使用下面的方法,這些方法適用於非同步操作模式。三 軟體層次的阻塞和非阻塞模式 1 阻塞模式 阻塞模式執行i o操作完成前會一直進行等待,不會將控制權交給程式,一般可以設定...

JS的同步與非同步

我們都知道js的 是同步執行的,也就是按照我們所書寫的順序一一執行,但是有3個特殊,他們屬於非同步執行 計時器 setinterval,settimeout 事件 onclick,onkeydown等 ajax 接下來我們分析比較一下同步執行的 和非同步執行的 之間的一些執行邏輯 1239 1011...