Yang03 / blog

0 stars 0 forks source link

event loop #14

Open Yang03 opened 7 years ago

Yang03 commented 7 years ago

event loop

event loop process model

当一个调用栈为空时,会执行下面的步骤:

  1. 从event loop 的task queue里选择一个最早的task(task A)
  2. 如果 task A 为空(意味着task queues为空),这时会跳到步骤 6
  3. 设置当前运行的task 为 “task A”
  4. 执行 "task A"
  5. 设置当前的运行task 为 null, 删掉"task A" 6.执行 microtask queue
    • (a) 从microtask queue 里面选择一个最早的task (task x)
    • (b) 如果task x 是空(意味着microtask queues为空),这时会跳到步骤 (g)
    • (c) 设置当前运行的task 为 “task x”
    • (d) 执行 "task x"
    • (e) 设置当前的运行task 为 null, 删掉"task x"
    • (f) 从microtask queue 里面选择一个下一个最早的task, 跳到步骤(b)
    • (g) 结束microtask queue
  6. 更新渲染
  7. 如果是一个woker event loop(如:WorkerGlobalScope)如果WorkerGlobalScope 已经关闭和event loop task queues 为空,会销毁这个event loop, 中止这个步骤,恢复运行[worker]:https://html.spec.whatwg.org/multipage/workers.html#workers 的步骤
  8. 返回到步骤 1

other

  1. 当一个macrotask 在运行时,可以注册新的事件,所以新的task 会被创建

    • promiseA.then() 的回调函数是一个task
    • resolved/rejected:会被pushed到mircrotask queue 中,在当前的事件循环中
    • pending: 会被pushed到mircrotask queue 中,在当前的事件循环中或者下一个循环中
    • setTimeout(callback, n) 会被pushed 到macrotask queue中,即使n=0
  2. task 在microtask 会在当前循环中执行,macrotask queue 会在下一个event loop 循环中

  3. click, ajax setTimeout 等的callback都是macrotask

    • macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
    • microtasks: process.nextTick, Promises, Object.observe, MutationObserver

参考链接

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
https://html.spec.whatwg.org/multipage/webappapis.html#task-queue
http://stackoverflow.com/questions/25915634/difference-between-microtask-and-macrotask-within-an-event-loop-context
https://vimeo.com/96425312
https://blog.risingstack.com/node-js-at-scale-understanding-node-js-event-loop/
https://cnodejs.org/topic/57d68794cb6f605d360105bf
Yang03 commented 7 years ago

https://github.com/creeperyang/blog/issues/21 http://fex.baidu.com/blog/2015/07/we-have-a-problem-with-promises/ http://www.ituring.com.cn/article/120765 https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ http://www.cnblogs.com/simonbaker/p/5715393.html https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Yang03 commented 7 years ago

EventLoop

先看下一段代码:

    function log(msg) {
        console.log(msg)
    }

    log('EventLoop')    

    setTimeout(function() {
        log('setTimeout')
    }, 100)

    setTimeout(function() {
        console.log('zero delay')
    },0)

函数调用会产生堆栈

wechatimg1

对象被分配在一个堆中,一个用以表示一个内存中大的未被组织的区域。

调用 setTimeout 函数会在一个时间段过去后在队列中添加一个消息。 如果队列中没有其它消息,消息会被马上处理。 但是,如果有其它消息,setTimeout 消息必须等待其它消息处理完。 第二个参数仅仅表示最少的时间 而非确切的时间

零延迟 (Zero delay) 并不是意味着回调会立即执行。在零延迟调用 setTimeout 时 ,其并不是过了给定的时间间隔后就马上执行回调函数。 其等待的时间基于队列里正在等待的消息数量

$('button').on('click', function onClick() {
    console.log('click')
})

当你点击按钮,会把function onClick 添加到队列中去,调用栈,会在空闲的时候去执行