Files
workspace/code/link/link-frontend/test.js
T
2025-12-27 17:21:38 +08:00

58 lines
1.5 KiB
JavaScript

function Snowflake() {
this.epoch = 1698796800000 // 自定义起始时间(毫秒)
this.machineId = 1 // 固定 machineId
this.sequence = 0
this.lastTimestamp = -1
this.sequenceBits = 12
this.machineBits = 10
this.maxSequence = 2 ** this.sequenceBits - 1 // 4095
}
// 获取当前时间(毫秒)
Snowflake.prototype.currentTime = function () {
return Date.now()
}
// 等待下一毫秒
Snowflake.prototype.waitNextMillisecond = function (lastTimestamp) {
let timestamp = this.currentTime()
while (timestamp <= lastTimestamp) {
timestamp = this.currentTime()
}
return timestamp
}
// 生成 BigInt ID
Snowflake.prototype.nextId = function () {
let timestamp = this.currentTime()
if (timestamp < this.lastTimestamp) {
throw new Error('Clock moved backwards. Refusing to generate id.')
}
if (timestamp === this.lastTimestamp) {
this.sequence = (this.sequence + 1) & this.maxSequence
if (this.sequence === 0) {
timestamp = this.waitNextMillisecond(this.lastTimestamp)
}
}
else {
this.sequence = 0
}
this.lastTimestamp = timestamp
const id
= (BigInt(timestamp - this.epoch) << BigInt(this.machineBits + this.sequenceBits))
| (BigInt(this.machineId) << BigInt(this.sequenceBits))
| BigInt(this.sequence)
return id
}
// 返回固定长度字符串 ID(适合数据库存储)
Snowflake.prototype.nextIdStr = function (padLength = 20) {
return this.nextId().toString().padStart(padLength, '0')
}