Js Snowflake(雪花算法)生成随机ID的实现方法


Posted in Javascript onAugust 26, 2020

1、snowflake-id插件 

import SnowflakeId from "snowflake-id";

const guid = num => {
 const id= new SnowflakeId();
 return id.generate();
};

2、原生使用 

var 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) {
			thrownew Error('_workerId must max than 0 and small than maxWrokerId-[' + this.maxWrokerId + ']');
		}
		if(this.dataCenterId > this.maxDataCenterId || this.dataCenterId < 0) {
			thrownew 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) {
			thrownew 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;
	};
	return Snowflake;
}());

console.log(new Snowflake(1n, 1n, 0n).nextId());
//1141531990672150528n

控制台输出1141531990672150528n为bigint格式, .toString()转为字符串格式即可

3、ES6使用

import bigInt from "big-integer";

const guid = () => {
 const Snowflake = /** @class */ (function() {
  function Snowflake(_workerId, _dataCenterId, _sequence) {
   // this.twepoch = 1288834974657;
   this.twepoch = 0;
   this.workerIdBits = 5;
   this.dataCenterIdBits = 5;
   this.maxWrokerId = -1 ^ (-1 << this.workerIdBits); // 值为:31
   this.maxDataCenterId = -1 ^ (-1 << this.dataCenterIdBits); // 值为:31
   this.sequenceBits = 12;
   this.workerIdShift = this.sequenceBits; // 值为:12
   this.dataCenterIdShift = this.sequenceBits + this.workerIdBits; // 值为:17
   this.timestampLeftShift = this.sequenceBits + this.workerIdBits + this.dataCenterIdBits; // 值为:22
   this.sequenceMask = -1 ^ (-1 << this.sequenceBits); // 值为:4095
   this.lastTimestamp = -1;
   //设置默认值,从环境变量取
   this.workerId = 1;
   this.dataCenterId = 1;
   this.sequence = 0;
   if (this.workerId > this.maxWrokerId || this.workerId < 0) {
    throw new Error(
     'config.worker_id must max than 0 and small than maxWrokerId-[' + this.maxWrokerId + ']'
    );
   }
   if (this.dataCenterId > this.maxDataCenterId || this.dataCenterId < 0) {
    throw new Error(
     'config.data_center_id must max than 0 and small than maxDataCenterId-[' +
      this.maxDataCenterId +
      ']'
    );
   }
   this.workerId = _workerId;
   this.dataCenterId = _dataCenterId;
   this.sequence = _sequence;
  }
  Snowflake.prototype.tilNextMillis = function(lastTimestamp) {
   var timestamp = this.timeGen();
   while (timestamp <= lastTimestamp) {
    timestamp = this.timeGen();
   }
   return timestamp;
  };
  Snowflake.prototype.timeGen = function() {
   //new Date().getTime() === Date.now()
   return 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 + 1) & this.sequenceMask;
    if (this.sequence === 0) {
     timestamp = this.tilNextMillis(this.lastTimestamp);
    }
   } else {
    this.sequence = 0;
   }
   this.lastTimestamp = timestamp;
   var shiftNum =
    (this.dataCenterId << this.dataCenterIdShift) |
    (this.workerId << this.workerIdShift) |
    this.sequence; // dataCenterId:1,workerId:1,sequence:0 shiftNum:135168
   var nfirst = new bigInt(String(timestamp - this.twepoch), 10);
   nfirst = nfirst.shiftLeft(this.timestampLeftShift);
   var nnextId = nfirst.or(new bigInt(String(shiftNum), 10)).toString(10);
   return nnextId;
  };
  return Snowflake;
 })();

 return new Snowflake(1, 1, 0).nextId();
};

guid()即可调用

4、多次重复调用出现一样id的bug

console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());
  console.log(guid(), new Date().getTime());

Js Snowflake(雪花算法)生成随机ID的实现方法

修改如下

import SnowflakeId from "snowflake-id";

const guid = num => {
 const snowflake = new SnowflakeId();
 let arr = [];
 for (let i = 0; i < num; i++) {
  arr.push(snowflake.generate());
 }
 return num ? arr : snowflake.generate();
};

单个调用 guid()

n个调用 guid(n)

文档

到此这篇关于Js Snowflake(雪花算法)生成随机ID的实现方法的文章就介绍到这了,更多相关Js 雪花算法生成随机ID内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
用javascript连接access数据库的方法
Nov 17 Javascript
jquery的颜色选择插件实例代码
Oct 02 Javascript
javascript面向对象之二 命名空间
Feb 08 Javascript
使用滤镜设置透明导致 IE 6/7/8/9 解析异常的解决方法
Apr 07 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
Jul 10 Javascript
正负小数点后两位浮点数实现原理及代码
Sep 06 Javascript
原生js ActiveXObject获取execl里面的值
Nov 01 Javascript
js改变Iframe中Src的方法
May 05 Javascript
angular中ui calendar的一些使用心得(推荐)
Nov 03 Javascript
详解小程序如何改变onLoad的执行时机
Nov 01 Javascript
Angular利用HTTP POST下载流文件的步骤记录
Jul 26 Javascript
解决基于 keep-alive 的后台多级路由缓存问题
Dec 23 Javascript
uin-app+mockjs实现本地数据模拟
Aug 26 #Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
Aug 25 #Javascript
微信小程序换肤功能实现代码(思路详解)
Aug 25 #Javascript
prettier自动格式化去换行的实现代码
Aug 25 #Javascript
Vue中 axios delete请求参数操作
Aug 25 #Javascript
React实现轮播效果
Aug 25 #Javascript
React实现全选功能
Aug 25 #Javascript
You might like
咖啡的种类和口感
2021/03/03 新手入门
Windows2003 下 MySQL 数据库每天自动备份
2006/12/21 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
PHP jQuery+Ajax结合写批量删除功能
2017/05/19 PHP
php通过pecl方式安装扩展的实例讲解
2018/02/02 PHP
php 使用mpdf实现指定字段配置字体样式的方法
2019/07/29 PHP
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
javascript日期格式化方法小结
2015/12/17 Javascript
JS获取IE版本号与HTML设置IE文档模式的方法
2016/10/09 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
详解webpack之scss和postcss-loader的配置
2018/01/09 Javascript
layui输入框只允许输入中文且判断长度的例子
2019/09/18 Javascript
js实现旋转木马轮播图效果
2020/01/10 Javascript
原生js+canvas实现下雪效果
2020/08/02 Javascript
Python中asyncore的用法实例
2014/09/29 Python
详解Python的迭代器、生成器以及相关的itertools包
2015/04/02 Python
简单介绍利用TK在Python下进行GUI编程的教程
2015/04/13 Python
Python实现将16进制字符串转化为ascii字符的方法分析
2017/07/21 Python
详解Python nose单元测试框架的安装与使用
2017/12/20 Python
分享一下Python数据分析常用的8款工具
2018/04/29 Python
PyCharm设置SSH远程调试的方法
2018/07/17 Python
PyQt5 多窗口连接实例
2019/06/19 Python
python3 反射的四种基本方法解析
2019/08/26 Python
python numpy存取文件的方式
2020/04/01 Python
python实现广度优先搜索过程解析
2019/10/19 Python
Python+OpenCV 实现图片无损旋转90°且无黑边
2019/12/12 Python
python爬虫用mongodb的理由
2020/07/28 Python
HTML5实现QQ聊天气泡效果
2017/06/26 HTML / CSS
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
西安夏日科技有限公司Java笔试题
2013/01/11 面试题
应届生会计电算化求职信
2013/10/03 职场文书
暑期实习鉴定
2013/12/16 职场文书
经典洗发水广告词
2014/03/13 职场文书
2014年局领导班子自身建设情况汇报
2014/11/21 职场文书
趣味运动会简讯
2015/07/20 职场文书
JavaCV实现照片马赛克效果
2022/01/22 Java/Android