###直接上代码
```
import http from 'node:http';
import { AsyncLocalStorage } from 'node:async_hooks';
import express, { NextFunction, Request, Response } from 'express';
const app = express();
const asyncLocalStorage = new AsyncLocalStorage();
// express 添加路由
app.use(async (req: Request, res: Response, next: NextFunction) => {
const storage = {
'x-request-id': req.query['x-request-id'] || '',
}
asyncLocalStorage.run(storage, () => {
logWithId('start');
// Imagine any chain of async operations here
setImmediate(() => {
logWithId('finish');
res.end()
});
});
});
app.listen(8080);
function logWithId(msg: any) {
const store = asyncLocalStorage.getStore() as any;
console.log(`${store['x-request-id']}:`, msg);
}
http.get('http://localhost:8080?x-request-id=1');
http.get('http://localhost:8080?x-request-id=2');
// 随机Prints:
// 1: start
// 2: start
// 1: finish
// 2: finish
```
### 代码分析,应用说明
1、使用express搭建web服务监听端口
2、AsyncLocalStorage 创建的实例(asyncLocalStorage)执行run方法,将第一个参数绑定到对应执行的第二个参数中;
asyncLocalStorage.run() 方法是在 Node.js 中用于创建一个异步本地存储(Async Local Storage)上下文并在此上下文中同步执行一个回调函数;
效果就是第二个函数作用域内任何地方通过实例获取到的storage都是第一个参数的值;
3、所以可以开发一个中间件,通过app.use全局注册。例如使用此中间件记录每一个请求头的x-request-id,后续调用下游服务的时候,就可以直接通过asyncLocalStorages实例调用固定方法 getStore获取传入的请求头信息,进而传给下游服务。