《深入浅出nodejs》异步I/O笔记(2)

Node的异步I/O:

              执行中创建请求对象,加入线程池,执行完成返回结果reault对象中的属性,作为I/O调用回调函数来达到异步的效果

              四要素: 事件循环 + 请求对象 + I/O线程池 + 观察者

 

       0.    node自身的循环模式

                        事件循环:


                            在进程启动的时候,node会创建一个类似于while(true)的循环,每执行一次循环体被称作tick。

                           

 

 

       0.    判断事件循环(生产者/消费者模型):

                    每个事件循环中有一个或者多个观察者,通过向观察者询问是否有需要处理的事务。

                     事件生产者:异步I/O,网络请求等

                    观察者:获取生产者传递的事件

                     事件循环:从观察者那里去处事件并进行处理

                            循环创建:windows->IOCP         unix->多线程

              ps:

                     浏览器的事件来源:用户的点击,加载文件,图片等

                    node的事件来源:    文件I/O,网络请求

                                   node观察者:文件I/O观察者,网络I/O观察者

 

深入:

       0.    请求对象

              对于一般的非异步回调函数,函数由开发者自身进行调用。

           eg:

                     function(list,callback){

                            for(var i=0; i<list.length;  i++){

                                   callback(list[i],i,list) ;

                            }

                     }

              对于node中的异步调用,回调函数由系统进行。

              eg: fs.open()打开文件调用图示:

                           

 

                     JS---调用--->node核心模块---调用--->C++内建模块(通过libuv系统调用) 

                     过程:windows------

                     ps:①libuv作为封装层,进行系统平台的判断。us_fs_open()方法。

                              ②us_fs_open()中,创建了了一个请求对象---FSRepWrap

                              ③FSReqWrap封装了 js层传入的参数和当前的方法,回调函数设置在oncomplete_sym属性上。

                              ④req_wrap ->object_ -> Set(omcomplete_sym, callback) ;

                              ⑤windows下,调用Qu e u eUs e rWorkItem()将FSReqWrap对象推入线程池中等待执行。

                             QueueUserWorkItem(

                                   &uv_fs_thread_proc:     将要执行方法的引用

                                   req:                                        uv_fs_thread_proc运行需要参数

                                   WT_EXECUTEDEFAULT:执行标志

                              )      

                             ⑥当线程池中有可用线程,调用fs_thread_proc()方法----根据传入参数的类型调用相应的底层函数

                             ⑦js返回。js发起的异步调用第一阶段结束

                             ⑧js线程继续执行当前任务的后续操作,当前的I/O操作在线程池中等待执行,不论是否阻塞I/O,都不会影响JS线程的后续执行,达到异步

 

 

       0.    回调通知:         组装好请求对象 -> 送入I/O线程池等待之后的下一部分

                            ①线程池中的I/O调用完成后,将获取的结果保存在req->result属性上

                            ②调用PostQueueCompletionStatus()通知IOCP,提示当前对象操作完成

                            PostQueueCompletionStatus():向IOCP提交执行状态,将线程归还线程池。

                            ③Tick执行中,调用GetQu e u e dCompletionStatus()检查是否有执行完的请求。存在,则将请求对象加入I/O观察者的队列,当作事件处理。

                            GetQueueCompletionStatus提取状态

                            ④I/O观察者回调函数:
 取出请求对象的result属性作为参数,取出complete_sym属性作为方法,调用执行,达到调j s中传入的回调函数目的。

                       

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值