js 雪花算法

非原创,代码来源找不到了,这里主要是记录代码,备用。


export const randomLenNum = (len, date) => {
  return tempSnowflake.getId()
}
export const Snowflake = /** @class */ (function() {
  function Snowflake(_workerId, _dataCenterId, _sequence) {
      this.twepoch = 1288834974657n;
      //this.twepoch = 0n;
      this.workerIdBits = 5n;
      this.dataCenterIdBits = 5n;
      this.maxWrokerId = -1n ^ (-1n << this.workerIdBits); // 值为:31
      this.maxDataCenterId = -1n ^ (-1n << this.dataCenterIdBits); // 值为:31
      this.sequenceBits = 12n;
      this.workerIdShift = this.sequenceBits; // 值为:12
      this.dataCenterIdShift = this.sequenceBits + this.workerIdBits; // 值为:17
      this.timestampLeftShift = this.sequenceBits + this.workerIdBits + this.dataCenterIdBits; // 值为:22
      this.sequenceMask = -1n ^ (-1n << this.sequenceBits); // 值为:4095
      this.lastTimestamp = -1n;
      //设置默认值,从环境变量取
      this.workerId = 1n;
      this.dataCenterId = 1n;
      this.sequence = 0n;
      if (this.workerId > this.maxWrokerId || this.workerId < 0) {
          throw new Error('_workerId must max than 0 and small than maxWrokerId-[' + this.maxWrokerId + ']');
      }
      if (this.dataCenterId > this.maxDataCenterId || this.dataCenterId < 0) {
          throw new Error('_dataCenterId must max than 0 and small than maxDataCenterId-[' + this.maxDataCenterId + ']');
      }

      this.workerId = BigInt(_workerId);
      this.dataCenterId = BigInt(_dataCenterId);
      this.sequence = BigInt(_sequence);
  }
  Snowflake.prototype.tilNextMillis = function(lastTimestamp) {
      var timestamp = this.timeGen();
      while (timestamp <= lastTimestamp) {
          timestamp = this.timeGen();
      }
      return BigInt(timestamp);
  };
  Snowflake.prototype.timeGen = function() {
      return BigInt(Date.now());
  };
  Snowflake.prototype.nextId = function() {
      var timestamp = this.timeGen();
      if (timestamp < this.lastTimestamp) {
          throw new Error('Clock moved backwards. Refusing to generate id for ' +
              (this.lastTimestamp - timestamp));
      }
      if (this.lastTimestamp === timestamp) {
          this.sequence = (this.sequence + 1n) & this.sequenceMask;
          if (this.sequence === 0n) {
              timestamp = this.tilNextMillis(this.lastTimestamp);
          }
      } else {
          this.sequence = 0n;
      }
      this.lastTimestamp = timestamp;
      return ((timestamp - this.twepoch) << this.timestampLeftShift) |
          (this.dataCenterId << this.dataCenterIdShift) |
          (this.workerId << this.workerIdShift) |
          this.sequence;
  };
  Snowflake.prototype.getId = function() {
    var timestamp = this.timeGen();
    if (timestamp < this.lastTimestamp) {
        throw new Error('Clock moved backwards. Refusing to generate id for ' +
            (this.lastTimestamp - timestamp));
    }
    if (this.lastTimestamp === timestamp) {
        this.sequence = (this.sequence + 1n) & this.sequenceMask;
        if (this.sequence === 0n) {
            timestamp = this.tilNextMillis(this.lastTimestamp);
        }
    } else {
        this.sequence = 0n;
    }
    this.lastTimestamp = timestamp;
    let id = ((timestamp - this.twepoch) << this.timestampLeftShift) |
    (this.dataCenterId << this.dataCenterIdShift) |
    (this.workerId << this.workerIdShift) |
    this.sequence;
    return BigInt(id).toString()
  };
  return Snowflake;
}());

var tempSnowflake = new Snowflake(1n, 1n, 0n);

关于在使用过程中,出现生成相同id的情况,正确用法是用同一个实例去生成,而非new xxx().nextId()这种形式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值