执行&异步 服务器端的I/O主要有两种情况:一是来自网络的I/O;二是对文件(设备)的I/O。Windows的异步I/O模型能很好的适用于这两种情况。而Linux针对前者提供了epoll模型,针对后者提供了AIO模型 线程池中的工作线程的数量与CPU内核数量相同,以此来最小化线程切换代价 消息队列 libuv V8执行栈 代码执行 ...执行fn1定义 调用fn1,调用console.log,调用createServer,调用方法时先为其创建上下文 上下文入栈 执行createServer方法 执行回调 发起http/fs异步调用请求,传递回调函数和执行上下文 新请求或异步操作完成,封装cb和result放入消息队列 消息中的callback和result入栈 执行完毕 若栈空,检查消息队列 没有监听器且队列为空 消息对象 IOCP on Win epoll on *nix 线程池 createServer上下文环境 fn1上下文环境 全局上下文环境 当前上下文中代码执行,变量赋值 (_,res)=>res.end('hi')上下文环境,闭包 全局上下文环境 var http = require('http') function startServer() { console.log('starting') http.createServer((_,res)=>res.end('hi')).listen(8000) console.log('started') } startServer() 创建全局上下文并入栈,然后执行全局代码 定义函数时会为其创建一个指向其定义时所在环境的scope属性 确定arguments(实参),函数声明(提升)-变量声明(提升)-作用域链scope-确定this 弹出栈 程序退出 这就解释了为什么那些回调函数的this指向window,因为这些异步的代码都是在全局上下文环境下执行的,但回调函数是个闭包,它保存了原来作用域的信息