事件循環機制及常見面試題

借鑒:

《Javascript 忍者秘籍》第二版,事件循環篇

面試 | JS 事件循環 event loop 經典面試題含答案 - 知乎 (zhihu.com)

概念

  1. 主棧隊列就是一個宏任務,每一個宏任務執行完就會執行宏任務中的微任務,直到微任務全部都執行完,才開始執行下一個宏任務。
  2. JS 中任務的執行順序優先級是:主棧全局任務(宏任務) > 宏任務中的微任務 > 下一個宏任務。,所以?promise(微任務).then()?的執行順序優先級高于setTimeout定時器。
  3. 不能滿目的將?.then?的回調放入微任務隊列;因為沒有調用?resolve或者reject?之前是不算異步任務完成的, 所以不能將回調隨意的放入微任務事件隊列
  4. await?是一個讓出線程的標志。await?后面的表達式會先執行一遍,將?await?后面的代碼加入到?micro task中這個微任務是?promise?隊列中微任務,然后就會跳出整個?async?函數來繼續執行后面的代碼。
  5. process.nextTick?是一個獨立于?eventLoop?的任務隊列,主棧中的宏任務每一次結束后都是先執行?process.nextTick隊列,在執行微任務?promise?的?.then()
  6. 每一個宏任務和宏任務的微任務執行完后都會對頁面 UI 進行渲染
  • 宏任務 macrotask
    • script 整體代碼
    • setTimeout
    • setInterval
    • setImmediate
    • I/O
    • ui render
  • 微任務 microtask
    • process.nextTick
    • promise.then
    • await 后面的代碼
    • MutationObserver(h5新特性)

為什么 await 后面的代碼會進入到promise隊列中的微任務?

async/await 只是操作 promise 的語法糖,最后的本質還是promise
async function async1() {console.log('async1 start');await async2();console.log('async1 end');
}
// 上面的代碼等價于 ==>
async function async1() {console.log('async1 start');Promise.resolve(async2()).then(() => {console.log('async1 end')})
}

面試題

面試題1

async function async1() {console.log('1') // 2async2().then(() => {console.log('2')})
}
async function async2() {console.log('3') // 3
}
console.log('4') // 1
setTimeout(function () {console.log('5')
}, 0)
async1();
new Promise(function (resolve) {console.log('6') // 4resolve();
}).then(function () {console.log('7')
})
console.log('8') // 5
//4 1 3 6 8 2 7 5

面試題2


setTimeout(() => {console.log(1);}, 0);async function main1() {new Promise((resolve, reject) => {console.log(2);resolve();}).then(() => {console.log(3);})await main2();console.log(7);}function main2() {console.log(8);}main1();setTimeout(() => {console.log(10);}, 0);//  
2
8
3
7
1
10

面試題3

Promise.resolve().then(() => {console.log(0);return Promise.resolve('4x');}).then((res) => { console.log(res) })
Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }, () => { console.log(2.1) }).then(() => { console.log(3); }).then(() => { console.log(5); }).then(() => { console.log(6); })// 0 1 2 3 4x 5 6

面試題4? 詳解:(1 封私信) 關于promise輸出順序的疑問? - 知乎 (zhihu.com)

new Promise((resolve,reject) => {console.log('外部promise')resolve()
})
.then(() => {console.log('外部第一個then')new Promise((resolve,reject) => {console.log('內部promise')resolve()}).then(() => {console.log('內部第一個then')return Promise.resolve()}).then(() => {console.log('內部第二個then')})
})
.then(() => {console.log('外部第二個then')
})
.then(() => {console.log('外部第三個then')
})
.then(() => {console.log('外部第四個then')
})	// 
外部promise外部第一個then內部promise
內部第一個then
外部第二個then
外部第三個then外部第四個then內部第二個then

面試題5

// A 任務
setTimeout(() => {console.log(1)
}, 20)// B 任務
setTimeout(() => {console.log(2)
}, 0)// C 任務
setTimeout(() => {console.log(3)
}, 10)// D
setTimeout(() => {console.log(5)
}, 10)console.log(4)
/* 輸出
*   4 -> 2-> 3 -> 5 -> 1
*/

面試題6

setTimeout(function () {console.log(1)
}, 0);new Promise(function (resolve, reject) {console.log(2)for (var i = 0; i < 10000; i++) {if (i === 10) {console.log(10)}i == 9999 && resolve();}console.log(3)
}).then(function () {console.log(4)
})
console.log(5);
// 2, 10, 3, 5, 4, 1

面試題7

console.log("start");
setTimeout(() => {console.log("children2")Promise.resolve().then(() =>{console.log("children3")})
}, 0)new Promise(function(resolve, reject){console.log("children4")setTimeout(function(){console.log("children5")resolve("children6")}, 0)
}).then(res =>{         // flagconsole.log("children7")setTimeout(() =>{console.log(res)}, 0)
})
// start children4 children2 children3  children5  children7 children6

面試題8

這道題的難點在于是?promise2還是?async1 end?先輸出。從全局宏任務之上而下執行時?await async2()?后面的代碼?console.log('async1 end')?先進入?promise?中的微任務隊列,最后.then()?中的console.log('promise2')?再進入到?promise?中的微任務隊列。所以再開始下一輪宏任務循環之前先輸出了?async1 end?再輸出了?promise2。全局中的微任務執行完成開始下一輪宏任務setTimeout?最后輸出?setTimeout

async function async1() {console.log('async1 start')await async2()console.log('async1 end')
}
async function async2() {console.log('async2')
}
console.log('script start')
setTimeout(function () {console.log('setTimeout')
}, 0)
async1()
new Promise((resolve) => {console.log('promise1')resolve()
}).then(function () {console.log('promise2')
})
console.log('script end')
//輸出
//script start
//async1 start
//async2
//promise1
//script end
//async1 end
//promise2
//setTimeout

面試題9?

首先開始全局下的宏任務依次輸出 script start, async1 start, promise1, promise3, script end。其中?await async2();async2()?中.then()的代碼先進入到promise的微任務隊列,await async2();?后面的代碼再進入到promise的任務隊列,console.log('promise4');?最后進入到?promise?的任務隊列。全局下的宏任務結束,開始全局下的微任務,promise 的微任務隊列中按照隊列的先進先出原則依次輸出,promise2,async1 end,promise4。全局微任務結束,開始下一輪的宏任務setTimeout,最終輸出?setTimeout

async function async1() {console.log('async1 start');await async2();console.log('async1 end');
}
async function async2() {new Promise(function (resolve) {console.log('promise1');resolve();}).then(function () {console.log('promise2');});
}
console.log('script start');
setTimeout(function () {console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {console.log('promise3');resolve();
}).then(function () {console.log('promise4');
});
console.log('script end');
//script start, 
// async1 start, 
// promise1, 
// promise3, 
// script end, 
// promise2,
// async1 end,
// promise4, 
// setTimeout

面試題10

async function async1() {console.log('async1 start');await async2();setTimeout(function() {console.log('setTimeout1')  // 這一部分代碼會放入到 promise 的微任務隊列中。},0)
}
async function async2() {setTimeout(function() {console.log('setTimeout2')},0)
}
console.log('script start');
setTimeout(function() {console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {console.log('promise1');resolve();
}).then(function() {console.log('promise2');
});
console.log('script end');
// script start, async1 start, promise1, script end,
// promise2, setTimeout3,  setTimeout2, setTimeout1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165468.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python 使用XlsxWriter操作Excel

在數據處理和報告生成的領域中&#xff0c;Excel 文件一直是廣泛使用的標準格式。為了讓 Python 開發者能夠輕松創建和修改 Excel 文件&#xff0c;XlsxWriter 庫應運而生。XlsxWriter 是一個功能強大的 Python 模塊&#xff0c;專門用于生成 Microsoft Excel 2007及以上版本&a…

Vue3-provide和inject

作用和場景&#xff1a;頂層組件向任意的底層組件傳遞數據和方法&#xff0c;實現跨層組件通信 跨層傳遞普通數據&#xff1a; 1.頂層組件通過provide函數提供數據 2.底層組件通過inject函數獲取數據 既可以傳遞普通數據&#xff0c;也可以使用ref傳遞響應式數據&#xff08…

批量插入SQL 錯誤 [933] [42000]: ORA-00933: SQL 命令未正確結束

使用DBeaver向【oracle數據庫】插入大量數據 INSERT INTO Student(name,sex,age,address,birthday) VALUES(Nike,男,18,北京,2000-01-01) ,(Nike,男,18,北京,2000-01-01) ,(Nike,女,18,北京,2000-01-01) ,(Nike,女,18,北京,2000-01-01) ,(Nike,男,18,北京,2000-01-01) ,(Nike…

使用Arrays.Sort并定制Comparator排序解決合并區間

合并區間-力扣算法題56題 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。 示例 1&#xff1a; 輸入&am…

新能源行業碳酸氫鋰純化除鈣鎂工藝

在碳酸氫鋰純化中常規的沉淀或者其它工藝不能夠滿足鈣鎂等堿土金屬的深度去除。通常采用離子交換工藝實現鈣離子、鎂離子的去除&#xff0c;以提升碳酸鋰的品質&#xff0c;但是國產樹脂在此行業應用中存在的使用量過大的問題&#xff0c;會導致設備造價偏高、廢水量太大&#…

C++二分向量算法:最多可以參加的會議數目 II

本題的其它解法 C二分算法&#xff1a;最多可以參加的會議數目 II 本文涉及的基礎知識點 二分查找算法合集 題目 給你一個 events 數組&#xff0c;其中 events[i] [startDayi, endDayi, valuei] &#xff0c;表示第 i 個會議在 startDayi 天開始&#xff0c;第 endDayi …

gitt開源項目的意義,公司為什么會對在gitt上有開源項目的人更大機會

Git是一種分布式版本控制系統&#xff0c;它可以幫助程序員管理代碼的歷史版本和協同工作。同時&#xff0c;Git也成為了開源項目的主要托管平臺之一。Git的開源項目意義重大&#xff0c;因為這種開源項目托管平臺可以幫助開發者將代碼和項目分享給全球的開發者&#xff0c;并且…

從0開始學習JavaScript--JavaScript元編程

JavaScript作為一門靈活的動態語言&#xff0c;具備強大的元編程能力。元編程是一種通過操作程序自身結構的編程方式&#xff0c;使得程序能夠在運行時動態地創建、修改、查詢自身的結構和行為。本文將深入探討JavaScript中元編程的各個方面&#xff0c;包括原型、反射、代理等…

2023亞太杯數學建模C題思路模型代碼

已完成C題思路代碼&#xff0c;文末名片獲取 C題是我們的一個數據分析問題&#xff0c;這個題目主要就是我們要去收集數據&#xff0c;清洗處理后進行分析。 問題1&#xff1a;分析影響中國新能源電動汽車發展的主要因素&#xff0c;建立數學模型&#xff0c;描述這些因素對中…

對未來新能源車測試工具的看法

汽車行業正在經歷變革的說法算是比較輕描淡寫的了&#xff0c;還記得我1983年加入這個行業時&#xff0c;行業聚焦點是引入發動機管理系統。當時還是以家庭掀背車為主的時代&#xff0c;發動機分析儀的體積像衣柜一樣大&#xff0c;還沒出現“CAN”通信協議。現在經常聽到我的導…

PHP預約上門回收廢品系統的代碼披露

PHP預約上門回收廢品系統的代碼披露 <?phpnamespace app\admin\controller;class Code {public function getTopDomainhuo(){error_reporting(0);$host $_SERVER["HTTP_HOST"];$matchstr "[^\\.]\\.(?:(" . $host . ")|\\w{2}|((" . $ho…

【第一部分:概述】ARM Realm Management Monitor specification

目錄 概述機密計算系統軟件組成MonitorRealmRealm Management Monitor (RMM)Virtual Machine (VM)HypervisorSecure Partition Manager (SPM)Trusted OS (TOS)Trusted Application (TA) Realm Management Monitor 參考文獻 概述 RMM是一個軟件組件&#xff0c;它構成了實現ARM…

機器學習筆記 - 復雜任務的CNN組合

基礎CNN架構可通過多種方式進行組合和擴展,從而解決更多、更復雜的任務。 1. 分類和定位 在分類和定位任務中,你不僅需要說出在圖像中找到的物體的類別,而且還需指出物體顯現在圖像中的邊界框坐標。這類任務假設在圖像中只有一個物體實例。 這個任務可通過在典型的分類網絡…

每日一題(LeetCode)----鏈表--兩數相加

每日一題(LeetCode)----鏈表–兩數相加 1.題目&#xff08;2. 兩數相加&#xff09; 給你兩個 非空 的鏈表&#xff0c;表示兩個非負的整數。它們每位數字都是按照 逆序 的方式存儲的&#xff0c;并且每個節點只能存儲 一位 數字。 請你將兩個數相加&#xff0c;并以相同形式返…

深入ReentrantReadWriteLock(一)

一、為什么要出現讀寫鎖 synchronized和ReentrantLock都是互斥鎖。 如果說有一個操作是讀多寫少的&#xff0c;還要保證線程安全的話。如果采用上述的兩種互斥鎖&#xff0c;效率方面很定是很低的。 在這種情況下&#xff0c;咱們就可以使用ReentrantReadWriteLock讀寫鎖去實現…

React16中打印事件對象取不到值的現象及其原因分析

React16中打印事件對象取不到值的現象及其原因分析 一、背景 在最近的開發過程中&#xff0c;遇到了一個看起來匪夷所思的問題?&#xff1a; <Inputplaceholder"請輸入"onChange{(e) > {console.log(e:, e)}}onKeyDown{handleKeyDown} />此時按理來說我…

旅行商問題(枚舉,回溯,動態規劃,貪心,分支界限)

文章目錄 問題描述暴力枚舉回溯法動態規劃法貪心法分支界限法 問題描述 假設有一個貨郎擔要拜訪n個城市&#xff0c;他必須選擇所要走的路程&#xff0c;路程的限制時每個城市只能拜訪一次&#xff0c;而且最后要走到原來出發的城市&#xff0c;要求路徑長度。 旅行商問題將要…

為銷售賦能:利用 Splashtop 增強遠程培訓技術

遠程銷售團隊這一概念在當今快節奏的商業環境中日益普遍。各公司正在計劃在不同地點靈活開展銷售業務&#xff0c;希望利用技術優勢縮小地域差距。但是&#xff0c;這種向遠程銷售的轉型面臨著重大挑戰&#xff0c;尤其在培訓和發展領域。培訓遠程銷售團隊需要采用創新方法&…

常見樹種(貴州省):012茶、花椒、八角、肉桂、杜仲、厚樸、枸杞、忍冬

摘要&#xff1a;本專欄樹種介紹圖片來源于PPBC中國植物圖像庫&#xff08;下附網址&#xff09;&#xff0c;本文整理僅做交流學習使用&#xff0c;同時便于查找&#xff0c;如有侵權請聯系刪除。 圖片網址&#xff1a;PPBC中國植物圖像庫——最大的植物分類圖片庫 一、茶 灌…