代码之家  ›  专栏  ›  技术社区  ›  linmu

为什么要回应。写阻止线程?

  •  0
  • linmu  · 技术社区  · 8 年前

    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模型。

    1 回复  |  直到 8 年前
        1
  •  1
  •   gregnr    8 年前

    好问题。

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

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

    当请求到来时,您的 server.on('request') 回调在主事件循环线程上执行。如果出现另一个请求,则在第一个回调和当前在主线程上执行的任何其他代码完成之前,其回调无法运行。

    大多数情况下,回调是短期的,因此您几乎不需要担心阻塞主线程。如果回调不是短期的,那么它们几乎总是调用一个与异步I/O相关的函数,该函数实际上在后台的不同线程中运行,因此释放了主线程以供其他代码执行。