一道题引起的EventLoop思考

题目背景

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'); 
复制代码

题目的本质,是考察setTimeoutpromiseasync await的实现顺序及JS的时间循环方面的相关问题。javascript

结果为: script start async1 start async2 promise1 script end async1 end promise2 settimeoutjava

这里涉及到同步异步MicrotasksMacrotasksMicrotasks优先级别高于Macrotasks 其中MicrotasksMacrotasks分别是:promise

microtasks:

  • process.nextTick
  • promise
  • Object.observe
  • MutationObserver

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI渲染
  1. 一个事件循环(event loop)会有一个或多个任务队列(task queue)
  2. task queue 就是 macrotask queue
  3. 每个 event loop 都有一个 microtask queue
  4. task queue == macrotask queue != microtask queue
  5. 一个任务 task 能够放入 macrotask queue 也能够放入 microtask queue 中

所以事件循环的顺序,决定了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。并发

Node.js的Event Loop

V8引擎解析JavaScript脚本。 解析后的代码,调用Node API。 libuv库负责Node API的执行。它将不一样的任务分配给不一样的线程,造成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。 V8引擎再将结果返回给用户。异步

浅谈event loopasync

相关文章
相关标签/搜索