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

ES6中Promise、async和await面試題整理

瀏覽:90日期:2022-06-01 16:36:52
目錄
  • 出題目的:
  • 知識點:
  • 代碼:
  • 附:promise與async await結合使用
  • 總結

學習過程中遇到的一些基礎的Promise、async、await面試題整理。

出題目的:

  • 考察 Promise、async、await 的基礎
  • 考察隊Event Loop、宏任務、微任務的理解

知識點:

  • JS 執行順序:單線程,自上而下、先同步后異步、先微任務后宏任務
  • new promise() -> Promise.resolve(),觸發then
  • new promise((reject)=>{reject()}) -> promise.reject(),觸發catch
  • then 和 catch 內部沒有 throw new Error 相當于 resolve
  • async function 相當于返回 Promise.resolve()
  • await 后面的代碼都是異步的,微任務;setTimeout是宏任務
  • 初始化Promise時,函數內部代碼會被立即執行

代碼:

考點1:Promise.resolve、Promise.reject執行順序

Promise.resolve().then(() => {  // 優先尋找then
		console.log(1);
	}).catch(() => {
		console.log(2);
	})
	// 1
Promise.reject().then(() => {  // 優先尋找catch
		console.log(1);
	}).catch(() => {
		console.log(2);
	})
	// 2

考點2:then 和 catch 內部沒有 throw new Error() 相當于 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

考點3:async function -> 相當于返回一個 Promise.resolve

const res = async function fn() {
	return 100;
}
console.log(res());  // 返回一個resolve狀態的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
})()

考點4: await 代碼執行順序

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
 */

考點5:Promise 與 setTimeout 執行順序

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后面的代碼為"微任務代碼"
}
async function fn2() {
	console.log("fn2");
}
console.log("start");
setTimeout(()=>{
	console.log("setTimeout");  // 宏任務 
});
fn1();
console.log("end");
/**
 * 打印順序:
 * start
 * fn1 start
 * fn2
 * end
 * fn1 end
 * setTimeout
 */

附:promise與async await結合使用

昨天看了一道字節外包的面試題

?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()

需要修改的是把同步執行的數組替換成換成異步打印。

在測試以后我們可以-驗證,forEach和for循環不同的是for循環可以修改數組的值,且forEach取不到具體某一項的值,這里的異步說的是每執行一次數組循環,就執行一步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()

總結

到此這篇關于ES6中Promise、async和await面試題整理的文章就介紹到這了,更多相關ES6 Promise、async、await面試題內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: JavaScript
国产综合久久一区二区三区