這篇文章將為大家詳細講解有關javascript異步的作用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
我們提供的服務有:成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、巴中ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的巴中網(wǎng)站制作公司什么是js異步?我們知道JavaScript的單線程的,這與它的用途有關。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點上添加內(nèi)容,另一個線程刪除了這個節(jié)點,這時瀏覽器應該以哪個線程為準?
所謂"單線程",就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執(zhí)行后面一個任務,以此類推。
這種模式的好處是實現(xiàn)起來比較簡單,執(zhí)行環(huán)境相對單純;壞處是只要有一個任務耗時很長,后面的任務都必須排隊等著,會拖延整個程序的執(zhí)行。常見的瀏覽器無響應(假死),往往就是因為某一段Javascript代碼長時間運行(比如死循環(huán)),導致整個頁面卡在這個地方,其他任務無法執(zhí)行。
ajax的同步請求就會導致瀏覽器產(chǎn)生假死,因為它會鎖定瀏覽器的UI(按鈕,菜單,滾動條等),并阻塞所有用戶的交互,jquery中的ajax有這樣一個同步請求的功能,一定要慎用,尤其是在請求的數(shù)據(jù)量很大的時候,要避免使用同步請求。
舉幾個栗子感受一下異步
后臺接口使用easy-mock,官方地址:https://easy-mock.com/
ajax使用axios,基本代碼如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>javascript異步</title> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <button>點擊</button> <script> { let myData = null //ajax請求 function ajax() { axios.get('https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock') .then(data => { console.log("ajax返回成功");// handle success myData = data.data console.log(myData); }) .catch(error => { // console.log(error); // handle error console.log("ajax返回失敗"); }) } } </script> </body> </html>
我們通過添加一些js來看下效果,
異步-定時器console.log(myData); setTimeout(() => { console.log('定時器'); }, 2000); console.log(myData);
輸出,應該沒什么懸念
//null //null //定時器
執(zhí)行順序:
先執(zhí)行第一個 console.log(myData);
然后遇到了定時器,將定時器掛起(就是暫停了這個定時器)
繼續(xù)執(zhí)行第二個 console.log(myData);
沒有可以執(zhí)行的js代碼,回頭把掛起的任務繼續(xù)執(zhí)行下去
繼續(xù)看下一個栗子
console.log(myData); ajax() console.log(myData);
看下輸出,依然沒有懸念
//null //null //ajax返回成功 //{success: true, data: {…}}(這是接口返回的數(shù)據(jù),我們不必關心返回的具體內(nèi)容,只要知道返回了就好,陌上寒注)
執(zhí)行順序和上面的定時器基本類似,不在此贅述。
將兩個栗子合并,我們看下
console.log(myData); ajax() setTimeout(() => { console.log('定時器'); }, 2000); console.log(myData);
輸出,
//null //null //ajax返回成功 //{success: true, data: {…}} //定時器
發(fā)現(xiàn)問題了嗎?兩個異步函數(shù)相遇了,先執(zhí)行誰?誰跑的快就先執(zhí)行誰?
也可以這么說,其實這引發(fā)了另外一個知識點,
兩個 console.log(myData);是同步執(zhí)行的,他們都在js的主線程上執(zhí)行,
在主線程之外還存在一個任務隊列,任務隊列中存放著需要異步執(zhí)行的內(nèi)容
當主線程運行完畢之后,就會去執(zhí)行任務隊列中的任務(不斷的重復掃描)直到任務隊列清空
觀察這段代碼
console.log(1); setTimeout(function () { console.log(2); }, 1000); console.log(3);
輸出:1,3,2,這沒什么可解釋的
再看一段代碼
setTimeout(function(){console.log(1);}, 0); console.log(2);
輸出:2,1,為什么會這樣?
console.log(2);在主線程中,先執(zhí)行,
setTimeout(function(){console.log(1);}, 0);放在了任務隊列中,
只有在主線程執(zhí)行完了才會去執(zhí)行任務列隊中的內(nèi)容
看這段代碼,有助于你的理解
console.log(myData); ajax() setTimeout(() => { console.log('定時器'); }, 2000); console.log(myData); const btn = document.querySelector('button') btn.onclick = () => { console.log("點擊了"); }
我們?yōu)閎utton按鈕添加了點擊事件,在瀏覽器刷新的同時不停地對按鈕進行點擊操作(當然是手動點擊)
看下輸出:
//null //null //(10次輸出)點擊了 //ajax返回成功 //{success: true, data: {…}} //定時器 //點擊了
這樣是不是可以理解為什么主線程要去循環(huán)掃描任務列隊了?
事件循環(huán)的每一輪稱為一個tick(有沒有聯(lián)想到vue中的nextTick?)
當產(chǎn)生用戶交互(鼠標點擊事件,頁面滾動事件,窗口大小變化事件等等),ajax,定時器,計時器等,會向事件循環(huán)中的任務隊列添加事件,然后等待執(zhí)行,
定時任務:setTimeout,setInverval
網(wǎng)絡請求:ajax請求,img圖片的動態(tài)加載
事件綁定或者叫DOM事件,比如一個點擊事件,我不知道它什么時候點,但是在它點擊之前,我該干什么還是干什么。用addEventListener注冊一個類型的事件的時候,瀏覽器會有一個單獨的模塊去接收這個東西,當事件被觸發(fā)的時候,瀏覽器的某個模塊,會把相應的函數(shù)扔到異步隊列中,如果現(xiàn)在執(zhí)行棧中是空的,就會直接執(zhí)行這個函數(shù)。
ES6中的Promise
在可能發(fā)生等待的情況
等待過程中不能像alert一樣阻塞程序的時候
因此,所有的“等待的情況”都需要異步
一句話總結就是需要等待但是又不能阻塞程序的時候需要使用異步
異步和并行千萬不要把異步和并行搞混了,
異步是單線程的,并行是多線程的
異步:主線程的任務以同步的方式執(zhí)行完畢,才會去依次執(zhí)行任務列隊中的異步任務
并行:兩個或多個事件鏈隨時間發(fā)展交替執(zhí)行,以至于從更高的層次來看,就像是同時在運行(盡管在任意時刻只處理一個事件)
關于javascript異步的作用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
網(wǎng)站欄目:javascript異步的作用-創(chuàng)新互聯(lián)
當前鏈接:http://jinyejixie.com/article48/dieoep.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供云服務器、面包屑導航、網(wǎng)站收錄、服務器托管、電子商務、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容