一文读懂异步和同步——async/await在运行时和普通代码的执行顺序的问题
async/await在运行时和普通代码的执行顺序的问题
一、执行顺序问题
JavaScript中的await语句是异步编程中用于等待Promise对象执行结果的关键字,它通常与async函数一起使用。在使用await关键字时,程序的执行将暂停,直到该关键字后面的Promise对象完成执行并返回结果。
函数代码执行顺序通常情况下按照代码所在文件从上至下的顺序执行,在执行到遇到异步操作时,会将该异步操作放入事件循环中,继续执行下面的同步代码,等异步操作结束后再执行回调函数或执行then方法所传入的回调函数。
JavaScript中的await语句是异步编程中用于等待Promise对象执行结果的关键字,它通常与async函数一起使用。在使用await关键字时,程序的执行将暂停,直到该关键字后面的Promise对象完成执行并返回结果。
函数代码执行顺序通常情况下按照代码所在文件从上至下的顺序执行,在执行到遇到异步操作时,会将该异步操作放入事件循环中,继续执行下面的同步代码,等异步操作结束后再执行回调函数或执行then方法所传入的回调函数。
举个例子:
async function test() {
console.log("start...")
await fetch('https://myapi.com/data') // 网络请求,会阻塞当前线程
console.log("end...")
}
test()
console.log("other code...")
执行结果为:
start...
other code...
end...
在代码执行过程中,先输出了"start..."和"other code...",说明异步代码的执行并没有阻塞其他同步代码的运行。直到异步代码中的网络请求完成之后,才会执行await之后的代码,输出"end..."。
需要注意的是,await只能在async函数中使用,而且如果await后面的Promise对象被reject了,那么await将抛出异常,因此建议在使用await时需要添加try-catch语句来处理异常情况。
再举个例子:
再看一道经典面试题:
执行顺序为ADCB 而不是 ADBC 为什么:
首先因为两个语句都是宏任务,没有微任务,所以两个优先级看起来是一样的,但是因为C的回调函数的延时时间为0因此其会作为异步任务(耗时任务)的第一个执行对象!!
二、JS任务详解
同步任务就是普通的代码 非耗时任务
异步任务则还分为两种:
其中宏任务里往往很多都是用微任务代码写的
每次执行完一个宏任务都会判断有没有微任务待执行,如果有,那么就先执行微任务再继续下一个宏任务
又一道经典面试题:
一开始看可能会觉得和上面那道面试题冲突了,其实不然 ,
因为我们要搞清楚thenFs.readFile().then()是宏任务还是微任务,结果其实我们理想的不一样,他和Promise().then()不一样,Promise().then()是微任务,而thenFs.readFile().then()是宏任务!!!
因此前面的面试题:
的执行结果为ADCB 而不是ADBC 因为他们两都是宏任务,又因为setTimeout的timeout为0 所以就先执行thenFs.then()了!!!
更多推荐
所有评论(0)