yjhjstz / deep-into-node

In-depth understanding of Node.js: Core Ideas and Source Code Analysis
https://jianghua-yjhs-organization.gitbook.io/in-depth-understanding-of-node.js-core-ideas-and/
4.36k stars 624 forks source link

有没有MicroTask和MacroTask的一些介绍呢 #11

Closed hyj1991 closed 7 years ago

hyj1991 commented 7 years ago

目前只看到Promise的Then方法注册的回调函数是在MicroTask队列中被依次执行的,还有别的方法是在MicroTask队列中执行的么?还有就是我搜遍源代码也没看到MacroTask队列的东西,请问这个到底是什么,用来执行哪些内容的呢?

hyj1991 commented 7 years ago

这个似乎算是V8引擎的部分了,不是Node的东西了,如果不方便回答的话我就关闭吧,感谢作者的分享,对我们这种菜鸟阅读源代码少走了很多弯路~

yjhjstz commented 7 years ago

MicroTask确实在 v8 层实现,我先上一张图,你先看看。 cy-m8dmuqaallep jpg-large

hyj1991 commented 7 years ago

看了下这个图,有几个疑问: 1.我目前看的源码是v6.9.1的,这里的process.nextTick的回调处理函数(nextTickQueue队列)是直接调用:

env->set_tick_callback_function(args[0].As<Function>());

的方式注册到Env的,然后在每一个异步回调中的AsyncWrap::MakeCallback中等待异步回调函数执行完成后,使用:

env()->tick_callback_function()->Call(process, 0, nullptr)

的方式被执行的,这样子看的话,Node实现的Promise.nextTick虽然确实也没走Event Loop,但是似乎也不算是在Microtask Queue中被执行的吧,可以这样认为么?(Promise.js的then方法实现确实看到了%EnqueueMicrotask这样的方式注册)

2.如何理解这里的Task Queue呢?看到您把microtask的部分放到这个Task Queue的中间,所以这个队列很像是事件循环中的每一次uv_run睡眠在uv_io_poll时收到定时器超时或者底层的kevent监听到响应事件时触发的回调函数组成的队列,因为我看到代码里每次执行microtask队列的点正是异步回调函数或者定时器超时的回调函数执行之后的。不知道这样理解对不对?

3.Stack部分的是函数调用嵌套栈还是独立的一个一个产生异步事件的函数呢?看图可能更像是前者,那么后面的BackGround Threads里面的是注册到Event Loop并且生成观察者的(uv_start_xxx())的那些异步函数吗?

问题有点多,不知道问的和理解的对不对,麻烦作者大大啦~

yjhjstz commented 7 years ago
  1. process.nextTickPromise 都用到了 v8 的 Microtask Queue
  2. Task Queue对于 setImmediate 来说就是: immediateQueue, javascript 层面实现是链表;
  3. Stack 是函数栈。BackGround 线程池运行同步调用比如 read
hyj1991 commented 7 years ago

结合图和您最后的解惑回答,感觉理解的更深了,非常感谢!