日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

在實例中重學JavaScript事件循環

瀏覽:181日期:2023-10-06 15:44:02

單線程的JS

眾所周知js是一門單線程語言,即同一時間只能做一件事。為什么js是單線程的呢,主要與它的用途有關。

作為瀏覽器腳本語言,js的主要用途是和用戶互動&操作DOM,我們并不想并行的操作DOM。如果不是單線程的話,我們一個線程在給DOM節點上添加內容,另一個線程卻刪除了這個節點,到底該以哪個為準呢?

所以為了避免復雜性,從一誕生,JavaScript 就是單線程。

事件循環(event loop)

JS是一門單線程語言,意味著代碼要一行一行的執行。所有任務都要排隊,前一個任務結束,才會執行后一個任務。

但平時大家開發時常用到的ajax,setTimeOut,promise之類的并沒有阻塞進程。如果瀏覽器只有一個js引擎構成,遇到上面這些比較耗時的請求或操作時,瀏覽器就會阻塞住,這肯定不是我們想要的。

其實js單線程是指瀏覽器在解釋和執行js代碼時只有一個線程,即js引擎線程。但瀏覽器還包括一些其他的線程來處理這些異步的方法,比如Web APIs線程,GUI渲染線程等。

事件循環的處理流程:

JS線程依靠調用棧來處理執行js代碼,當遇到一些異步的操作時,則將其移交給Web APIs,自己繼續往下進行。Web APIs線程則將收到的事件按一定的規則和順序添加到任務隊列里去。JS線程處理完當前所有任務(即執行棧為空),則去檢查任務隊列里是否有等待被處理的事件,若有,則取出一個事件回調放入執行棧中執行。然后不斷循環第三步。

宏任務與微任務

任務隊列又分為宏任務隊列和微任務隊列:

宏任務隊列(macrotask queue):存放的是setTimeout, setInterval, setImmediate, I/O, UI rendering等。 微任務隊列(microtask queue):存放的是Promises, Object.observe, MutationObserver,process.nextTick等。

所以我們細化一下事件循環的處理流程(瀏覽器環境):

JS線程依靠調用棧來處理執行js代碼,當遇到一些異步的操作時,則將其移交給Web APIs,自己繼續往下進行。Web APIs線程則將收到的事件按一定的規則和順序添加到任務隊列里去。宏任務事件則添加到宏任務隊列,微任務事件則添加到微任務隊列。JS線程處理完當前所有任務(即執行棧為空),會先去微任務隊列檢查是否有待處理的事件,若有,會將微任務隊列里的所有事件一件件執行完直到微任務隊列為空,再去宏任務隊列取出最前面的一個事件執行,執行完這一個宏任務事件后再去檢查微任務隊列是否有事件待處理。然后不斷循環第三步。

實際需求中重學JavaScript事件循環

什么是JS事件循環?

在秋招的時候經常會被問到這個問題,但自己的理解僅限于以上,然后刷過幾道輸出值順序的題目,沒有過業務中的實際應用場景。后來拿到offer后就忘的一干二凈了,直到畢業入職后開始寫代碼重新遇到了這才有了更深一步的理解。

背景用戶上傳多張圖片,前端拿到每張圖片的url和寬高發送給后端。

解決首先是拿到用戶上傳的文件,做一些校驗和限制

// 調用系統彈框添加圖片的方法addFile(e) { let uploadFiles = e.target.files,self = this; self.getListData = []; // 要傳給后端的對象數組 self.testFiles(uploadFiles) // 對用戶上傳的文件做一些校驗和限制 self.loadAll(uploadiles) // 調用loadAll方法},

然后讓我們看一下loadAll,主要是遍歷上傳的這些圖片文件,然后每一個圖片文件都調用了loadImg

loadAll(files) { let promises = [],self = this // 遍歷文件流 files.forEach((file,i) => { // 創建對象,push到數組里 (self.getListData).push({ imageUrl: ’’, }); let eachPromise = self.loadImg(file,i) // 存儲當前promise對象 promises.push(eachPromise) }) Promise.all(promises).then(() => { //全部完成,向后端發送請求 }).catch(err => { console.log(err) })},

然后讓我們看一下loadImg,這個方法返回一個Promise對象,主要是為了保證拿到圖片的URL以及在img.onload里拿到圖片的寬高,因為這兩個事件都是異步事件。

實際上js主線程是不會等待這兩個結果,就會繼續往下執行的。但因為我們在img.onload里才會把Promise給resolve出去,而loadAll方法里用了一個Promise.all來等待所有promise都完成,這樣就可以保證向后端發送請求時所有的圖片的url和寬高都能拿到。

loadImg(file,i) { return new Promise(async (resolve,reject) => { let self = this // 調用公司wos服務,拿圖片文件的url let successRes = await _fileUpload.uploadFile(item) if(successRes && successRes !== ’error’){ self.getListData[i][’imageUrl’] = successRes.url } let img = new Image() img.src = successRes.url img.onload = () => { self.getListData[i][’width’] = img.width self.getListData[i][’height’] = img.height resolve() } img.onerror = (e) => { reject(e) } })}

讓我們想一下如果把loadImg里拿圖片的url這個操作放到loadAll里呢?

loadAll(files) { let promises = [],self = this // 遍歷文件流 files.forEach(async(file,i) => { // 創建對象,push到數組里 (self.getListData).push({ imageUrl: ’’, }); // 調用公司wos服務,拿圖片文件的url let successRes = await _fileUpload.uploadFile(item) if(successRes && successRes !== ’error’){ self.getListData[i][’imageUrl’] = successRes.url } let eachPromise = self.loadImg(file,i) // 存儲當前promise對象 promises.push(eachPromise) }) Promise.all(promises).then(() => { //全部完成,向后端發送請求 }).catch(err => { console.log(err) })},

如果變成這種寫法,因為js的主線程執行棧不會等待await返回結果,循環里await _fileUpload.uploadFile(item)這行代碼后面的內容會被交給Web APIs然后跳出async函數。繼續執行主線程,而現在Promise.all的參數是一個空數組,然后就直接發了請求。但現在并沒有拿到圖片的URL和寬高。

關鍵字await只能使async函數一直等待,執行棧當然不可能停下來等待的,await將其后面的內容包裝成Promise交給Web APIs后,執行棧會跳出async函數繼續執行,直到Promise執行完并返回結果。await只在async函數里面奏效。

總結

從上面這個需求的實現中,好像對事件循環的理解更深刻了!像Promise.then里和await后面的代碼都會等待返回結果后再被放入對應事件的任務隊列中等待執行,JS線程會繼續向下執行調用棧。包括vue中的watch handler也是被先放入了任務隊列里等待。

所以可知事件循環在實際工作中對寫代碼和優化代碼都非常重要~如理解有誤請在評論區多多指教。

以上就是在實例中重學JavaScript事件循環的詳細內容,更多關于JavaScript 事件循環的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
香蕉久久99| 国产精品毛片在线| 国产欧美亚洲精品a| 国产亚洲一区| 精品久久国产一区| 亚洲爱爱视频| 国产免费成人| 午夜久久av| 国产欧美高清| 日本一区二区免费高清| 激情欧美丁香| 亚洲欧美网站在线观看| 国产精品高清一区二区| 日韩天堂在线| 日本在线视频一区二区| 国产一区二区久久久久| 午夜国产欧美理论在线播放| 日韩精品导航| 麻豆精品蜜桃| 免费日本视频一区| 精品国产乱码久久久| 不卡一区2区| 欧美日韩一视频区二区| 国产成人在线中文字幕| 羞羞答答国产精品www一本| 国产精品sm| 九一成人免费视频| 国产精品一页| 在线综合亚洲| 福利片在线一区二区| 99国产精品99久久久久久粉嫩| 国产九一精品| 99在线观看免费视频精品观看| 国产无遮挡裸体免费久久| 久久久国产精品一区二区中文| 日本在线成人| 久久国产电影| 国产精品男女| 国产一级久久| 国产一区二区三区亚洲综合| 蜜臀精品一区二区三区在线观看| 精品国产91| 午夜精品福利影院| 亚洲婷婷免费| 你懂的国产精品永久在线| 午夜欧美精品| 成人片免费看| 国产精品视频一区二区三区四蜜臂 | 中文字幕日韩高清在线 | 久久成人福利| 亚洲少妇自拍| 日韩欧美精品一区| 免费观看亚洲天堂| 日韩高清在线观看一区二区| 欧美日韩国产亚洲一区| 精品国产精品国产偷麻豆| 亚洲精品一二三**| 午夜在线播放视频欧美| 在线观看精品| 激情中国色综合| 日韩精品久久理论片| 99在线观看免费视频精品观看| 精品国产一区二区三区2021| 视频一区中文字幕精品| 国产毛片一区| 欧美成人亚洲| 亚洲91视频| 91看片一区| 国产精品任我爽爆在线播放| 亚洲色图网站| 免费在线观看成人| 午夜在线视频观看日韩17c| 激情视频一区二区三区| 国产亚洲一区二区手机在线观看| 国产精品18| 欧美综合精品| 日韩精品久久久久久久软件91| 国产视频一区三区| 美女久久网站| 人人爽香蕉精品| 美女日韩在线中文字幕| 红桃视频欧美| 国产精品视区| 国产精品嫩草99av在线| 国产精品嫩草99av在线| 狠狠干综合网| 国产亚洲精品自拍| 另类av一区二区| 亚洲香蕉视频| 日本aⅴ免费视频一区二区三区| 亚洲精品极品| 日本一区二区三区中文字幕| 亚洲视频国产| 日韩激情综合| 国产精品欧美一区二区三区不卡| 亚洲精品日本| 久久精品国产亚洲夜色av网站| 日韩伦理在线一区| 四虎影视精品| 亚洲黄页一区| 亚洲精品美女91| 国产美女精品视频免费播放软件| 国产欧美日韩一级| 精品一区二区三区中文字幕| 福利一区二区| 日韩成人a**站| 欧美在线观看视频一区| 欧美日韩激情| 中文字幕免费精品| 国产精品va视频| 天堂√中文最新版在线| 影音先锋久久| 91欧美日韩在线| 国产suv精品一区| 欧美日韩色图| 亚洲精品在线二区| 久久精品二区亚洲w码| 日韩精品免费一区二区三区| 2023国产精品久久久精品双| 综合干狼人综合首页| 国产午夜久久av| 中文一区一区三区高中清不卡免费| 日韩中文在线电影| 丝袜美腿一区二区三区| 国产欧美日韩亚洲一区二区三区| 国产一区二区三区亚洲| 合欧美一区二区三区| 欧美日韩一区自拍| 欧美成a人免费观看久久| 亚洲精品自拍| 国产精品毛片一区二区在线看| 五月综合激情| 国产免费av国片精品草莓男男| av免费不卡国产观看| 天使萌一区二区三区免费观看| 欧美亚洲二区| 日本精品影院| 亚洲资源网站| 福利精品在线| 少妇精品久久久一区二区| 黄毛片在线观看| 日韩**一区毛片| 久久久久久美女精品| 欧美日韩在线精品一区二区三区激情综合 | 国产精品视频一区视频二区| 色婷婷精品视频| 欧美一级二区| 亚洲二区精品| 国产精选一区| 欧美中文一区二区| 国产精品黄色片| 日韩精品一级二级| 色综合www| 国产精品99久久免费观看| 亚洲中午字幕| 亚洲黄色免费av| 国产剧情一区| 日韩中文字幕麻豆| 日本高清不卡一区二区三区视频| 日本成人在线网站| 国产一区欧美| 国产美女高潮在线观看| 日本久久二区| 久久亚洲欧洲| 欧美+亚洲+精品+三区| 国产欧美三级| 亚洲精品系列| 国产精品老牛| 久久国产毛片| 91日韩免费| 九九久久国产| 国产美女亚洲精品7777| 亚洲免费专区| 国产精品丝袜xxxxxxx| 亚洲精品在线影院| 精品网站aaa| 欧美极品中文字幕| 久久国产乱子精品免费女| 中文字幕一区二区三区日韩精品 | av亚洲免费| 欧美成人a交片免费看| 你懂的国产精品| 欧美在线观看天堂一区二区三区| 久热精品在线| 欧美精品一线| 国产综合精品| 国产尤物精品| 午夜欧美巨大性欧美巨大| 国产成人免费精品| 精品香蕉视频| 国产精品1luya在线播放| 欧美视频久久| 国产亚洲人成a在线v网站 | 亚洲精品伦理| 亚洲伊人精品酒店| 亚洲美女久久| 日韩欧美中文字幕电影| 日韩欧美美女在线观看| 日韩精选在线| 欧美视频一区|