×

ES6经常会被问到的面试题:对Promise、async和await的理解

作者:Terry2023.03.03来源:Web前端之家浏览:2022评论:0
关键词:Promise

promise是每个前端人必须会接触到的一个知识点,下面这篇文章主要给大家介绍了关于ES6中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()


您的支持是我们创作的动力!
温馨提示:本文作者系Terry ,经Web前端之家编辑修改或补充,转载请注明出处和本文链接:
https://www.jiangweishan.com/article/Promise20230303.html

网友评论文明上网理性发言 已有0人参与

发表评论: