您好,登錄后才能下訂單哦!
前言
我本來是打算寫一篇co源碼精讀(為啥讀co,因為它短),然鵝發現自己存在一系列基礎問題沒有搞透徹,打算寫一個js基礎系列文章,總結自己的理解(copy),希望與你在學習路上一同進步。首先問問自己當面試官問到js中的同步和異步,這個問題該怎么回答?理解一個問題無非是what-why-how
js同步和異步問題是什么-->為什么會產生異步問題-->如何解決。
一、JavaScript起源
技術的出現,和應用場景密切相關的。JavaScript誕生于1995年。當時,它的主要目的是處理以前由服務器端語言(如Perl)負責的一些輸入驗證操作。在JavaScript問世之前,必須把表單數據發送到服務器端才能確定用戶是否沒有填寫某個必填域,是否輸入了無效的值。Netscape Navigator希望通過JavaScript來解決這個問題。起初名字為livescript,但是后來Netscape(網景)與Sun公司成立了一個開發聯盟。Netscape為了搭上媒體熱炒Java的順風車,臨時把LiveScript改名為JavaScript,所以從本質上來說JavaScript和Java沒什么關系(趁熱度)。
如今,JavaScript的用途早已不再局限于簡單的數據驗證,而是具備了與瀏覽器窗口及其內容等幾乎所有方面交互的能力。今天的JavaScript已經成為一門功能全面的編程語言
總結:js最初的用途是為來實現用戶與瀏覽器的交互
二、JS為何是單線程的?
JavaScript的單線程,與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準?
所以,為了避免復雜性,從一誕生,JavaScript就是單線程,這已經成這門語言的核心特征,將來也不會改變。
注:所謂單線程,是指在JS引擎中負責解釋和執行JavaScript代碼的線程只有一個。
三、計算機的同步與異步(重點)
計算機領域中的同步(Synchronous)和異步(Asynchronous)和我們生活中的同步和異步的概念是恰好相反的,感覺是翻譯要背這個鍋。生活中的同步,突出的是‘同',相同的步伐,是咱倆一起行動,比如一起去逛街吃飯飯睡覺覺。異步則是你忙你的,我忙我的,步調不致且互不干擾。難到計算機里的同步和異步不是這樣?確實不是。
計算機的同步就好比:你去外地上學人生地不熟,突然生活費不夠了;此時你決定打電話回家,通知家里轉生活費過來,可是當你撥出電話時,對方一直處于待接聽狀態(即:打不通,聯系不上),為了拿到生活費,你就不停的oncall、等待,最終可能不能及時要到生活費,導致你今天要做的事都沒有完成,而白白花掉了時間。
計算機的異步就是:在你打完電話發現沒人接聽時,猜想:對方可能在忙,暫時無法接聽電話,所以你發了一條短信(或者語音留言,亦或是其他的方式)通知對方后便忙其他要緊的事了;這時你就不需要持續不斷的撥打電話,還可以做其他事情;待一定時間后,對方看到你的留言便回復響應你,當然對方可能轉錢也可能不轉錢。但是整個一天下來,你還做了很多事情。或者說你找室友臨時借了一筆錢,又開始happy的上學時光了。
總結:計算機中的同步就是排隊等待,假如你是第一百零一個備胎,那你只能等前面的一百個爆了之后才能‘處理'你。異步就是,盡管你是第一百零一個,她還是能照顧到你的感受。
四、js單線程為什么會有'異步'問題
看完前面的鋪墊你是否會產生這些疑問,JS是單線程的,那么他是如何是實現異步操作的?AJAX異步發送和回調請求,還有setTimeout也看起來像是多線程的?不急慢慢來
是的,單線程,那肯定只能同步(排隊)執行咯
如果JS中不存在異步,只能自上而下執行,萬一上一行解析時間很長,那么下面的代碼就會被阻塞。
對于用戶而言,阻塞就意味著"卡死",這樣就導致了很差的用戶體驗
通過事件循環(event loop)實現'異步'
經典問題:
console.log('1') setTimeout(function(){ console.log('2') },0) console.log('3') // 1,3,2
也就是說,setTimeout里的函數并沒有立即執行,而是延遲了一段時間,滿足一定條件后,才去執行的,這類代碼,我們叫異步代碼。
所以,這里我們首先知道了JS里的一種分類方式,就是將任務分為: 同步任務和異步任務
雖然JS是單線程的但是瀏覽器的內核是多線程的,在瀏覽器的內核中不同的異步操作由不同的瀏覽器內核模塊調度執行,異步操作會將相關回調添加到任務隊列中。而不同的異步操作添加到任務隊列的時機也不同,如 onclick, setTimeout, ajax 處理的方式都不同,這些異步操作是由瀏覽器內核的 webcore 來執行的,webcore 包含上圖中的3種 webAPI,分別是 DOM Binding、network、timer模塊。
按照這種分類方式:JS的執行機制是
以上三步循環執行,這就是event loop
總結:同步可以保證順序一致,但是容易導致阻塞;異步可以解決阻塞問題,但是會改變順序性,根據不同的需要去寫你的代碼。
每周都會持續更新,您的點贊,收藏,關注三連擊是我的動力。
決定了前方的路怎么走,就不要總回頭看,peace&love。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。