Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

event loop #14

Open
Yang03 opened this issue Dec 6, 2016 · 2 comments
Open

event loop #14

Yang03 opened this issue Dec 6, 2016 · 2 comments

Comments

@Yang03
Copy link
Owner

Yang03 commented Dec 6, 2016

event loop

  • 一个eventloop有一个或者多个task queues(任务队列),一个task queues由有序任务列表组成
  • 每一个evnt loop都有一个microtask queue
  • task queue = macrotask != microtask
  • 一个task会被pushed 到一个macrotask queue 或者microtask queue
  • 当一个task pushed 到一个queue(micro/macro), 一位着准备工作已经结束,task可以执行了

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
  1. task 在microtask 会在当前循环中执行,macrotask queue 会在下一个event loop 循环中

  2. 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
Copy link
Owner Author

Yang03 commented Mar 21, 2017

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 添加到队列中去,调用栈,会在空闲的时候去执行

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant