one command at one time
單執行緒,其實指的就是一次執行一個指令
用人來比喻就是,一次只能做一件事情
相反的,多執行緒就是同個時間能夠執行多個指令
不過要注意的是,雖然 javascript 本身是單執行緒,但是瀏覽器本身不是,因為瀏覽器上不是只有 javascript
one at one time
一次執行一行,並且按照程式碼出現的順序。
我知道他的意思跟「同步」這個詞的字面上好像互斥,其實在程式上就不要想是我們平常的意思。
同步和非同步,我記得有人有個神比喻:
想像有一家超商有一個店員,這時客人很多在排隊,因為只有一個店員,所以一次只能服務一個客人。
而當只有一個收銀台時,剛好這個客人掏錢掏很慢,店員只能乾巴巴的等他,後面的客人繼續等,終於十分鐘後客人掏出錢來,店員終於能結帳,才換下一位客人,這就是「同步」。
同樣的情況,假設有兩個收銀台,當目前的客人A掏錢掏很慢,店員此時決定先幫下一個客人B結帳,終於十分鐘後客人A掏出錢來,店員再幫他結帳,這就是「非同步」。
(如果有錯再提醒我謝謝)
先談談 invocation
,這是指透過 ()
呼叫函數
來看一個簡單的例子
function b () {
}
function a () {
b();
}
a();
當執行 javascript 會先發生什麼?
首先會先建立全域執行環境,這時之前提到的第一階段會先創建全域物件和 this ,還有將變數放進記憶體,第二階段開始執行程式碼
執行時,碰到了 a();
他會呼叫 a 函數,這時會創造一個「a 函數的執行環境」並堆在全域執行環境上方,請看下圖。
這就是執行堆(the exxecution stack)的概念。
當新的執行環境被建立,就跟全域執行環境一樣,會歷經創造階段,一樣會將變數和函數放進記憶體,然後一樣執行程式碼。
執行時,碰到了 b();
他呼叫了 b 函數,這時又創造了「b 函數的執行環境」,並堆在 a 執行環境上。
目前在執行堆上的執行環境就是目前正在執行的,當目前的執行環境執行完畢後,就會離開執行堆,然後繼續執行最上層的執行環境(好繞口)
以上面的例子來說,假設 b()
執行完了,他就會從執行堆上離開,變成 a()
在最上層,於是會從 a()
剛剛還沒執行到下一行開始,當 a()
也執行完畢,就會從執行堆上離開,接著就會回到全域執行環境,繼續執行還沒被執行到的。