Skip to content

https://nodejs.org/api/async_context.html

AsyncLocalStorageNode.js 中用于管理异步上下文中的存储数据的一个类,属于 async_hooks 模块的一部分。

它允许在多个异步操作之间共享和追踪上下文数据,而不必显式地传递这些数据。

该方法是 Node.js 对于 CLS 的原生方法实现。

js
const http = require('http')
const { AsyncLocalStorage } = require('async_hooks')

const asyncLocalStorage = new AsyncLocalStorage()

const server = http.createServer((req, res) => {
  const requestId = Math.floor(Math.random() * 1000)

  asyncLocalStorage.run(new Map(), () => {
    asyncLocalStorage.getStore().set('requestId', requestId)

    processRequest(req, res)
  })
})

function processRequest(req, res) {
  // Simulate some asynchronous work
  setTimeout(() => {
    const requestId = asyncLocalStorage.getStore().get('requestId')
    res.end(`Handled request with ID: ${requestId}\n`)
    console.log(asyncLocalStorage.getStore())
  }, 100)
}

server.listen(3000, () => {
  console.log('Server is running on port 3000')
})

上面的脚本首先创建了一个新的 AsyncLocalStorage 实例,然后创建了一个简单的 HTTP 服务器。在每个请求处理过程中,它都会创建一个随机的请求 ID,并将其存储在一个新的 Map 中,然后使用 asyncLocalStorage.run() 方法将这个 Map 存储在当前异步上下文中。

js
const { createServer } = require('node:http')
const { v4:uuidv4 } = require('uuid')
const port = 8000

const server = createServer((req, res) => {
  const uuid = uuidv4()
  const { url } = req
  res.setHeader('uuid', uuid)
  // console.log(req, res)
  if (url === '/test') {
    res.end('Test')
    return
  }
  res.end('Home')
})

server.listen(port, () => {
  console.log(`http://localhost:${port}`)
})