ES6中Promise、async和await面試題整理
學(xué)習(xí)過程中遇到的一些基礎(chǔ)的Promise、async、await面試題整理。
出題目的:
- 考察 Promise、async、await 的基礎(chǔ)
- 考察隊(duì)Event Loop、宏任務(wù)、微任務(wù)的理解
知識點(diǎn):
- JS 執(zhí)行順序:單線程,自上而下、先同步后異步、先微任務(wù)后宏任務(wù)
- new promise() -> Promise.resolve(),觸發(fā)then
- new promise((reject)=>{reject()}) -> promise.reject(),觸發(fā)catch
- then 和 catch 內(nèi)部沒有 throw new Error 相當(dāng)于 resolve
- async function 相當(dāng)于返回 Promise.resolve()
- await 后面的代碼都是異步的,微任務(wù);setTimeout是宏任務(wù)
- 初始化Promise時,函數(shù)內(nèi)部代碼會被立即執(zhí)行
代碼:
考點(diǎn)1:Promise.resolve、Promise.reject執(zhí)行順序
Promise.resolve().then(() => { // 優(yōu)先尋找then console.log(1); }).catch(() => { console.log(2); }) // 1
Promise.reject().then(() => { // 優(yōu)先尋找catch console.log(1); }).catch(() => { console.log(2); }) // 2
考點(diǎn)2:then 和 catch 內(nèi)部沒有 throw new Error() 相當(dāng)于 resolve
Promise.resolve().then(() => { console.log(1); }).catch(() => { console.log(2); }).then(() => { console.log(3); }) // 1 3
Promise.reject().then(() => { console.log(1); }).catch(() => { console.log(2); }).then(() => { console.log(3); }) // 2 3
Promise.reject().then(() => { console.log(1); }).catch(() => { console.log(2); throw new Error(); }).then(() => { console.log(3); }) // 2 報錯
Promise.reject().then(() => { console.log(1); }).catch(() => { console.log(2); throw new Error(); }).then(() => { console.log(3); }).catch(() => { console.log(4); }) // 2 4
考點(diǎn)3:async function -> 相當(dāng)于返回一個 Promise.resolve
const res = async function fn() { return 100; } console.log(res()); // 返回一個resolve狀態(tài)的Promise對象 Promise {<fulfilled>: 100} res().then(()=>{ console.log(0); }).catch(()=>{ console.log(1); }) // 0 (async function () { const a = fn(); const b = await fn(); console.log(a); // Promise {<fulfilled>: 100} console.log(b); // 100 })()
考點(diǎn)4: await 代碼執(zhí)行順序
async function fn1() { console.log("fn1 start"); await fn2(); console.log("fn1 end"); } async function fn2() { console.log("fn2 start"); } console.log("start"); fn1(); console.log("end"); /** * 打印順序: * start * fn1 start * fn2 start * end * fn1 end */
async function fn1() { console.log("fn1 start"); await fn2(); console.log("fn1 end"); await fn3(); console.log("fn3 end"); } async function fn2() { console.log("fn2"); } async function fn3() { console.log("fn3"); } console.log("start"); fn1(); console.log("end"); /** * 打印順序: * start * fn1 start * fn2 * end * fn1 end * fn3 * fn3 end */
考點(diǎn)5:Promise 與 setTimeout 執(zhí)行順序
console.log("start"); setTimeout(()=>{ console.log("setTimeout") }); Promise.resolve().then(()=>{ console.log("Promise") }) console.log("end") /** * 打印順序: * start * end * Promise * setTimeout */
async function fn1() { console.log("fn1 start"); await fn2(); console.log("fn1 end"); // await后面的代碼為"微任務(wù)代碼" } async function fn2() { console.log("fn2"); } console.log("start"); setTimeout(()=>{ console.log("setTimeout"); // 宏任務(wù) }); fn1(); console.log("end"); /** * 打印順序: * start * fn1 start * fn2 * end * fn1 end * setTimeout */
附:promise與async await結(jié)合使用
昨天看了一道字節(jié)外包的面試題
?const list = [1, 2, 3]; ? ? const square = num => { ? ? ? ? return new Promise((resolve, reject) => { ? ? ? ? ? ? setTimeout(() => { ? ? ? ? ? ? ? ? resolve(num * num); ? ? ? ? ? ? }, 1000); ? ? ? ? }); ? ? } ? ? function test() { ? ? ? ? // 修改這里的代碼 ? ? ? ? list.forEach(async x => { ? ? ? ? ? ? const res = await square(x); ? ? ? ? ? ? console.log(res); ? ? ? ? }); ? ? } ? ? test()
需要修改的是把同步執(zhí)行的數(shù)組替換成換成異步打印。
在測試以后我們可以-驗(yàn)證,forEach和for循環(huán)不同的是for循環(huán)可以修改數(shù)組的值,且forEach取不到具體某一項(xiàng)的值,這里的異步說的是每執(zhí)行一次數(shù)組循環(huán),就執(zhí)行一步test()方法,
const list = [1, 2, 3]; const square = num => { ?? ?return new Promise((resolve, reject) => { ?? ??? ?setTimeout(() => { ?? ??? ??? ?resolve(num * num); ?? ??? ?}, 1000); ?? ?}); } ?function test() { ? for(let x of list) { ? ? var res = await square(x) ? ? console.log(res) ? } } test()
總結(jié)
到此這篇關(guān)于ES6中Promise、async和await面試題整理的文章就介紹到這了,更多相關(guān)ES6 Promise、async、await面試題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS實(shí)現(xiàn)網(wǎng)頁上隨機(jī)產(chǎn)生超鏈接地址的方法
這篇文章主要介紹了JS實(shí)現(xiàn)網(wǎng)頁上隨機(jī)產(chǎn)生超鏈接地址的方法,涉及JavaScript隨機(jī)數(shù)的相關(guān)使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11JavaScript實(shí)現(xiàn)網(wǎng)頁動態(tài)生成表格
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)網(wǎng)頁動態(tài)生成表格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-11-11原生js實(shí)現(xiàn)addClass,removeClass,hasClass方法
這篇文章主要介紹了原生js實(shí)現(xiàn)addClass,removeClass,hasClass方法和使用原生JS實(shí)現(xiàn)jQuery的addClass, removeClass, hasClass函數(shù)功能,需要的朋友可以參考下2016-04-04JS實(shí)現(xiàn)完全語義化的網(wǎng)頁選項(xiàng)卡效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)完全語義化的網(wǎng)頁選項(xiàng)卡效果代碼,可實(shí)現(xiàn)基于鼠標(biāo)滑過及點(diǎn)擊的選項(xiàng)卡切換效果,非常具有實(shí)用價值,需要的朋友可以參考下2015-09-09JS定時器使用,定時定點(diǎn),固定時刻,循環(huán)執(zhí)行詳解
下面小編就為大家?guī)硪黄狫S定時器使用,定時定點(diǎn),固定時刻,循環(huán)執(zhí)行詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05點(diǎn)擊button獲取text內(nèi)容并改變樣式的js實(shí)現(xiàn)
這篇文章主要介紹了點(diǎn)擊button獲取text內(nèi)容并改變樣式的js實(shí)現(xiàn),經(jīng)測試非常實(shí)用,需要的朋友可以參考下2014-09-09