一、單執行緒
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...