NodeJs - 实现当前线程唯一的单例对象
- 一. 实现当前线程唯一的单例对象
一. 实现当前线程唯一的单例对象
Java
里面,一般都把这种和当前线程绑定的单例对象存储到ThreadLocal
里面,但是Node
里面没有这种存储,那咋办呢?直接上代码:
const cluster = require('cluster');
class Context {
constructor() {
this.id = Math.random().toString(36).substring(2);
}
static create() {
if (cluster.isWorker) {
if (!cluster.worker.hasOwnProperty('_context')) {
cluster.worker._context = new Context();
}
return cluster.worker._context;
} else {
if (!global.hasOwnProperty('_context')) {
global._context = new Context();
}
return global._context;
}
}
static release(){
if (cluster.isWorker) {
if (cluster.worker.hasOwnProperty('_context')) {
delete cluster.worker._context;
}
} else {
if (global.hasOwnProperty('_context')) {
delete global._context;
}
}
}
}
module.exports = Context;
在create
方法中:
- 我们首先检查当前进程/线程是否是一个工作进程。
- 如果是工作进程,我们使用
cluster.worker
对象来存储和获取Context
对象。 - 每个工作进程都有自己的上下文,因此在每个工作进程中创建的
Context
对象都是唯一的。
如果当前进程/线程不是一个工作进程,我们使用global
对象来存储和获取Context
对象。在这种情况下,Context
对象在整个进程/线程中都是唯一的。
测试代码:
const Context = require('./context');
(async () => {
// 循环10次,每次创建一个新的Context实例,异步创建
const promiseList = []
for (let i = 0; i < 5; i++) {
const context = Context.create();
console.log('sync', context.id);
promiseList.push(test());
}
await Promise.all(promiseList);
// 清除这个对象,让下一次请求能够重新再赋值一个新的Context
Context.release();
})();
async function test() {
setTimeout(() => {
const context = Context.create();
console.log('async', context.id);
}, 2000);
}
结果如下: