async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log('script end');
复制代码
题目的本质,是考察setTimeout
、promise
、async await
的实现顺序及JS的时间循环方面的相关问题。javascript
结果为: script start async1 start async2 promise1 script end async1 end promise2 settimeout
java
这里涉及到同步异步Microtasks
和Macrotasks
。 Microtasks
优先级别高于Macrotasks
其中Microtasks
、Macrotasks
分别是:promise
所以事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(总体代码)开始第一次循环。以后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),而后执行全部的micro-task。当全部可执行的micro-task执行完毕以后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,而后再执行全部的micro-task,这样一直循环下去。浏览器
首先,要明确的一点:javascript是以单线程的方式运行的。JavaScript的主要用途是与用户互动,以及操做DOM。若以多线程的方式,则可能出现冲突。假设有两个线程同时操做一个DOM元素,线程1要求浏览器删除DOM,而线程2却要求修改DOM样式,这时浏览器就没法决定采用哪一个线程的操做。固然,咱们能够为浏览器引入“锁”的机制来解决这些冲突,但大大提升复杂性,因此 JavaScript从诞生开始就选择了单线程执行。在某一时刻内只能执行特定的一个任务,而且会阻塞其它任务执行。 可是JavaScript 有个基于“Event Loop”并发的模型(不是并行)。前者是逻辑上的同时发生,然后者是物理上的同时发生。因此,单核处理器也能实现并发。 上图说明一下并发和并行:bash
小tips:多线程
console.log(1);
setTimeout(function(){
console.log(2);
Promise.resolve(1).then(function(){
console.log('ok')
})
})
setTimeout(function(){
console.log(3)
})
复制代码
分析:先默认走栈,输出1。此时并无微任务,因此微任务不会执行。先走第一个setTimeout,输出2,同时将微任务放到队列中,执行微任务,输出ok,微任务执行完,再走宏任务,输出3。并发
V8引擎解析JavaScript脚本。 解析后的代码,调用Node API。 libuv库负责Node API的执行。它将不一样的任务分配给不一样的线程,造成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。 V8引擎再将结果返回给用户。异步
浅谈event loopasync