为什么 response.write 会阻塞线程?

why does response.write block the thread?

下面是示例:

const http = require('http')
const server = http.createServer()
const log = console.log.bind(console)

server.on('request', (req, res) => {
    log('visited!')
    res.writeHead(200, {
        'Content-Type': 'text/html; charset=utf-8',
    })
    for (let i = 0; i < 100000; i++) {
        res.write('<p>hello</p>')
    }
    res.end('ok')
})


server.listen(3000, '0.0.0.0')

服务器在处理第一个请求时,线程阻塞,无法处理第二个请求。我想知道为什么会发生这种情况,因为 nodejs 使用事件驱动、非阻塞 I/O 模型。

好问题。

NodeJS 使用非阻塞 I/O 模型;也就是说,I/O 操作将 运行 在引擎盖下的单独线程上,但所有 JavaScript 代码将 运行 在同一事件循环驱动的线程上。

在您的示例中,当您要求 HTTP 服务器侦听传入请求时,Node 将在后台管理单独线程上的套接字侦听操作,以便您的代码可以在调用后继续 运行 server.listen().

当请求到来时,您的 server.on('request') 回调将在主事件循环线程上执行。如果另一个请求进来,它的回调不能 运行 直到第一个回调和当前在主线程上执行的任何其他代码完成。

大多数时候,回调是短暂的,因此您很少需要担心阻塞主线程。如果回调不是短暂的,它们几乎总是调用异步 I/O 相关函数,该函数实际上在引擎盖下的不同线程中执行 运行,因此释放主线程以供其他代码使用执行。