我不是 node 程序员,但我对the single-threaded non-blocking IO model的工作原理感兴趣.

c.query(
   'SELECT SLEEP(20);',
   function (err, results, fields) {
     if (err) {
       throw err;
     }
     res.writeHead(200, {'Content-Type': 'text/html'});
     res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');
     c.end();
    }
);

Que:当有两个请求A(先到)和B时,因为只有一个线程,服务器端程序将首先处理请求A:执行SQL查询是代表I/O等待的Hibernate 语句.程序被困在I/O等待,无法执行导致网页延迟的代码.在等待过程中,程序会切换到请求B吗?在我看来,由于采用单线程模型,无法从一个请求切换到另一个请求.但是示例代码的标题是everything runs in parallel except your code.

(P.S.我不确定我是否误解了代码,因为我已经误解了

推荐答案

node .js建立在libuv之上,这是一个跨平台库,它为支持的操作系统(至少包括Unix、OS X和Windows)提供的异步(非阻塞)输入/输出抽象API/syscall.

异步io

在这个编程模型中,对文件系统don't block the calling thread管理的设备和资源(套接字、文件系统等)执行打开/读/写操作(与典型的同步类c模型一样),只需标记进程(在内核/OS级数据 struct 中),以便在新数据或事件可用时通知.对于类似web服务器的应用程序,流程负责确定通知事件属于哪个请求/上下文,并从那里继续处理请求.请注意,这必然意味着您将处于与向操作系统发出请求的堆栈帧不同的堆栈帧上,因为后者必须向进程的调度程序屈服,以便单线程进程处理新事件.

我描述的模型的问题是,它并不熟悉,程序员也很难推理,因为它本质上是非顺序的."您需要在函数A中发出请求,并在另一个函数中处理结果,而在该函数中,您来自A的本地人通常不可用."

node 的模型(延续传递样式和事件循环)

Node通过 bootstrap 程序员采用某种编程风格,利用javascript的语言特性来解决这个问题,使这个模型看起来更同步.每个请求IO的函数都有一个function (... parameters ..., callback)这样的签名,需要给它一个回调,在请求的操作完成时调用(请记住,大部分时间都花在等待操作系统发出完成信号上——这段时间可以用来做其他工作).Javascript对闭包的支持允许您使用在回调主体内部的外部(调用)函数中定义的变量——这允许在 node 运行时独立调用的不同函数之间保持状态.另见第Continuation Passing Style页.

此外,在调用生成IO操作的函数后,调用函数通常会将return个控件发送到 node 的event loop.该循环将调用计划执行的下一个回调或函数(很可能是因为操作系统通知了相应的事件)——这允许并发处理多个请求.

您可以将 node 的事件循环想象为somewhat similar to the kernel's dispatcher:一旦挂起的IO完成,内核将安排执行一个阻塞的线程,而 node 将在相应的事件发生时安排回调.

高度并发,没有并行性

最后一句话,短语"除代码外,所有东西都并行运行"很好地说明了一点,即node允许代码通过在单个执行流中对所有js逻辑进行多路复用和排序,同时处理来自hundreds of thousands open socket with a single thread的请求(尽管这里说"所有东西都并行运行"可能不正确——请参阅Concurrency vs Parallelism - What is the difference?).这对于webapp服务器来说非常有效,因为大多数时间实际上都花在等待网络或磁盘(数据库/套接字)上,而且逻辑不是真正的CPU密集型——也就是说:this works well for IO-bound workloads.

Node.js相关问答推荐

Twilio-获取呼叫录音不起作用的请求

如何在Mongoose中调用动态Collection ?

对于具有重叠列的组合键,在冲突&q;上没有唯一或排除约束匹配错误

如何使用Nextjs路由从下一步/导航在新选项卡中通过";router.ush";打开链接

未显示NPM版本

EJS ForEach循环标记

如何发送比特币BTC使用发送加密使用WIF密钥在 node ,js

PEAN auth 应用程序:为什么 Angular 拦截器总是使用BehaviorSubject 返回 null(即初始值),而不是更新后的值?

发布请求不使用 Nodejs 更新 MongoDB 中的标头信息

Docker node_modules 文件夹上的 React 应用程序不可用

如何解决 npm install react-select failure with error : An unknown git error occurred, git@github.com :Permission denied (publickey)

'{ id: string; 类型的参数}' 不可分配给FindOneOptions类型的参数

为什么在调用数据库调用时我的参数没有定义?

NestJS TypeORM 可选查询不起作用

Socket IOFlutter 未连接

bash:npm:找不到命令?

如何在 Node.js 中逐字节读取二进制文件

在 PassportJS 中使用多种本地策略

分块 WebSocket 传输

在多个 .env 文件之间切换,例如 .env.development 和 node.js