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学习基础笔记之DOM对象操作
Nov 03 Javascript
解析prototype,JQuery中跳出each循环的方法
Dec 12 Javascript
JQuery菜单效果的两个实例讲解(3)
Sep 17 Javascript
javascript实现别踩白块儿小游戏程序
Nov 22 Javascript
AngularJs 弹出模态框(model)
Apr 07 Javascript
javascript表单事件处理方法详解
May 15 Javascript
JavaScript实现复制文章自动添加版权
Aug 02 Javascript
jquery表单验证实例仿Toast提示效果
Mar 03 Javascript
JS实现的走迷宫小游戏完整实例
Jul 19 Javascript
利用HBuilder打包前端开发webapp为apk的方法
Nov 13 Javascript
JS控制鼠标拒绝点击某一按钮的实例
Dec 29 Javascript
详解vuex结合localstorage动态监听storage的变化
May 03 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
Smarty Foreach 使用说明
2010/03/23 PHP
php simplexmlElement操作xml的命名空间实现代码
2011/01/04 PHP
php通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
JavaScript 判断浏览器类型及版本
2009/02/21 Javascript
通过DOM脚本去设置样式信息
2010/09/19 Javascript
js getBoundingClientRect() 来获取页面元素的位置
2010/11/25 Javascript
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
2013/10/17 Javascript
浏览器图片选择预览、旋转、批量上传的JS代码实现
2013/12/04 Javascript
ajax请求乱码的解决方法(中文乱码)
2014/04/10 Javascript
js获取浏览器基本信息大全
2014/11/27 Javascript
c#+jquery实现获取radio和checkbox的值
2020/09/12 Javascript
js的window.showModalDialog及window.open用法实例分析
2015/01/29 Javascript
javascript中caller和callee详解
2015/08/10 Javascript
基于JavaScript实现树形下拉框
2016/08/10 Javascript
JS封装通过className获取元素的函数示例
2016/12/20 Javascript
jQuery中on方法使用注意事项详解
2017/02/15 Javascript
使用jquery datatable和bootsrap创建表格实例代码
2017/03/17 Javascript
原生JS进行前后端同构
2018/04/22 Javascript
浅谈Vue中render中的h箭头函数
2019/11/07 Javascript
JavaScript实现单点登录的示例
2020/09/23 Javascript
深入理解javascript中的this
2021/02/08 Javascript
Python中使用支持向量机SVM实践
2017/12/27 Python
对pandas的行列名更改与数据选择详解
2018/11/12 Python
几个适合python初学者的简单小程序,看完受益匪浅!(推荐)
2019/04/16 Python
python连接、操作mongodb数据库的方法实例详解
2019/09/11 Python
python Scrapy框架原理解析
2021/01/04 Python
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
毕业生求职简历中的自我评价
2013/10/18 职场文书
思想品德自我评价
2014/02/04 职场文书
八一建军节活动方案
2014/02/10 职场文书
建筑结构施工专业推荐信
2014/02/21 职场文书
护士工作心得体会
2016/01/25 职场文书
python缺失值填充方法示例代码
2022/12/24 Python