面试的时候遇到这样一个问题:
输出结果如下:
1、JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事,所以计算是从上而下的,所以先输出script begin;
2、为了防止js在执行多个任何的时候,耗时长,造成阻塞,所以js语言将任务执行模式分为同步和异步,其实定时器、promise回调,async,事件的绑定等都属于异步操作。只要在函数名之前加上async关键字,就表明这个函数内部有异步操作,但是它和普通函数的区别也只是返回的是promise。
对于await来说:分两种结果
如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。
3、所以遇到await之后先执行外面的同步代码,对于promise来说promise实例中是同步操作,promise的回调函数里面是异步操作,所以输出5555。同步代码执行完之后,回到async内部执行。
4、对于定时器和promise需要依赖事件循环的宏任务和微任务来解释。
先遇到setTimeout,那么将其回调函数注册后分发到宏任务Event Queue。
接下来遇到了Promise,new Promise立即执行,then函数分发到微任务Event Queue。
遇到console.log(),立即执行。
好啦,整体代码script作为第一个宏任务执行结束,看看有哪些微任务?我们发现了then在微任务Event Queue里面,执行。
ok,第一轮事件循环结束了,我们开始第二轮循环,当然要从宏任务Event Queue开始。我们发现了宏任务Event Queue中setTimeout对应的回调函数,立即执行。
所以微任务会早与宏任务执行。