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 遍历页面text控件详解
Jan 06 Javascript
jQuery中is()方法用法实例
Jan 06 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
Mar 13 Javascript
js实现类似菜单风格的TAB选项卡效果代码
Aug 28 Javascript
javascript每日必学之运算符
Feb 16 Javascript
Javascript同时声明一连串(多个)变量的方法
Jan 23 Javascript
canvas实现简易的圆环进度条效果
Feb 28 Javascript
jQuery判断邮箱格式对错实例代码讲解
Apr 12 jQuery
解决Vue 通过下表修改数组,页面不渲染的问题
Mar 08 Javascript
angular中如何绑定iframe中src的方法
Feb 01 Javascript
VUE安装使用教程详解
Jun 03 Javascript
关于vue.js中实现方法内某些代码延时执行
Nov 14 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
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
js prototype截取字符串函数
2010/04/01 Javascript
高效的表格行背景隔行变色及选定高亮的JS代码
2010/12/04 Javascript
ExtJS4 组件化编程,动态加载,面向对象,Direct
2011/05/12 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
在javascript中实现函数数组的方法
2013/12/25 Javascript
js实现选中复选框文字变色的方法
2015/08/14 Javascript
JavaScript核心语法总结(推荐)
2016/06/02 Javascript
jQuery 3.0 的 setter和getter 模式详解
2016/07/11 Javascript
Bootstrap实现带动画过渡的弹出框
2016/08/09 Javascript
jquery实现下拉框多选方法介绍
2017/01/03 Javascript
JavaScript之Canvas_动力节点Java学院整理
2017/07/04 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
Node.js成为Web应用开发最佳选择的原因
2018/02/05 Javascript
微信小程序实现循环动画效果
2018/07/16 Javascript
jQuery内容选择器与表单选择器实例分析
2019/06/28 jQuery
layui实现下拉框三级联动
2019/07/26 Javascript
微信小程序清空输入框信息与实现屏幕往上滚动的示例代码
2020/06/23 Javascript
Vue-router编程式导航的两种实现代码
2021/03/04 Vue.js
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
Python中使用Tkinter模块创建GUI程序实例
2015/01/14 Python
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
python实现词法分析器
2019/01/31 Python
Python代码太长换行的实现
2019/07/05 Python
python3.8下载及安装步骤详解
2020/01/15 Python
pandas分批读取大数据集教程
2020/06/06 Python
举例讲解Python装饰器
2020/12/24 Python
彪马英国官网:PUMA英国
2019/02/11 全球购物
计算机系本科生求职信
2014/05/31 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
党的群众路线教育实践活动总结材料
2014/10/30 职场文书
Python提取PDF指定内容并生成新文件
2021/06/09 Python
Python基于百度API识别并提取图片中文字
2021/06/27 Python
Django路由层如何获取正确的url
2021/07/15 Python