我們都知道javascript是單線程的,node.js是一個基於Chrome V8 引擎的 javascript 運行時環境,注意 node.js 不是一門語言,別搞錯了。
javascript為什么是單線程的,這么做有什么好處?
因為歷史原因,js的出現主要是為了解決頁面的交互和操作DOM,如果是多線程的,就會帶來比較復雜的同步問題。
比如兩個線程同時操作一個DOM,那最終頁面顯示上會以哪個線程操作為准,這就是個問題。而單線程就沒有這種問題。
創建線程是需要消耗資源的,早期js是嵌在網頁中被瀏覽器解釋運行的,如果是多線程那必然會消耗比較多的資源,顯然與js的定位不符。
還有多線程之間的上下文切換也會比較消耗時間,這也是js是單線程的原因,估計js單線程這個特征以后也不會改變。
單線程的好處:1、沒有線程間同步問題。2、節省創建線程資源。3、節省上下文切換時間。
但是單線程也有問題,所有的操作都必須一個一個來,如果中間有一個操作非常耗時,那整個運行都會阻塞在那里。
為了解決這個問題,js引入了事件和回調函數機制,對於一個IO操作,比如一個ajax,當發出一個異步請求后,程序不會阻塞在那里等待結果的返回,而是繼續執行下面的代碼。
當請求成功獲取到結果后,就會調用回調函數來處理后面的事情,這個就是異步的非阻塞。
當然,異步 與 非阻塞,同步 與 阻塞,這兩者之間概念很容易搞混。
一、同步與異步關注的是消息的通知方式。
同步,當發起一個調用時,在沒有獲取結果之前,調用不會返回,直到獲取結果。事一件一件做,做完一件再做下一件。
異步,當發起一個調用時,在沒有獲取結果之前,調用就返回了,調用者並不會立即得到結果,而是被調用者通知調用者。通過回調函數處理結果。
二、阻塞與非阻塞關注的是等待結果(返回值)時的狀態
阻塞,在等待結果的過程中,不能干其他事,線程被掛起,直到結果返回。
非阻塞,在等待結果的過程中,還能干其他事,線程不會被阻塞。
同步阻塞方式:
比如,你打電話問老婆今晚吃什么,老婆在電話那邊一直想啊想,你在電話這邊不干別的,就一直等啊等,電話始終未掛,直到她說吃火鍋,電話才掛掉。
同步非阻塞方式:
比如,你打電話問老婆今晚吃什么,老婆在電話那邊一直想啊想,你在電話這邊該干什么干什么,電話始終未掛,直到她說吃火鍋,電話才掛掉。
異步阻塞方式:
比如,你打電話問老婆今晚吃什么,老婆說我想想,過一會跟你打話。你在電話這邊什么也沒干,就一直等着這個電話。
異步非阻塞方式:
比如,你打電話問老婆今晚吃什么,老婆說我想想,過一會跟你打話。你在電話這邊想干什么干什么,如果有電話來了,再處理電話。
同步與異步是被調用方決定的,決定是馬上給你答案,還是過會通知你,給你答案。
阻塞與非阻塞是調用方決定的,在等待結果的過程中, 是否還可以干其他事。