vue.js js 雪花算法ID生成 vue.js之snowFlake算法

发布时间:2024年01月20日

随着前端业务越来越复杂,自定义表单数据量比较大,每条数据的id生成则至关重要。想到前期IOS中实现的雪花算法ID,照着其实现JS版本,供大家学习参考。

一、库的建立引入

在你项目中创建一个snowFlake.js的文件:拷贝以下内容进去。

import bigInt from 'big-integer'

export default class SnowFlake {
    constructor(_workerId=1, _dataCenterId=1, _sequence=0) {
        // 开始时间截 (2012-01-01),这个可以设置开始使?该系统的时间,可往后使?69年
        this.twepoch = 1325347200000;
        this.workerIdBits = 5;
        this.dataCenterIdBits = 5;
        this.maxWorkerId = -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.workdId = 1;
        this.dataCenterId = 1;
        this.sequence = 0;

        if (this.workdId > this.maxDataCenterId || this.workdId < 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;
    }

    tilNextMillis(lastTimestamp) {
        var timestamp = this.timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = this.timeGen();
        }
        return timestamp;
    }

    timeGen() {
        return Date.now();
    }

    nextId() {
        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;
    }
    /**
      * 获取更安全的随机ID(解决连续输出id会出现重复的问题)
      * 尽可能的避免重复
      * @param {int} repeatRate 重复率默认值100(注释:最?是1,最?值越?,重复的概率越低,不过还需要考虑性能的问题,并不是越?越好,只是相对??)   */
    flakeId(repeatRate = 1) {
        let arr = []
        let ranNum = Math.floor(window.crypto.getRandomValues(new Uint8Array(1)) * 0.001 * repeatRate)
        for (let index = 0; index < repeatRate; index++) {
            arr[index] = this.nextId()
        }

        return arr[ranNum]
    }
}


const snowflake = new SnowFlake();

export function snowFlakeId(val) {
    return snowflake.flakeId();
}

因为生成的id比较大,普通的int类型无法保持精度,故而引入了big-integer这个类库。完成以上粘贴事宜后,进入你的项目,安装依赖:

如果你使用的是npm来管理依赖库则运行:

npm install big-integer --save

如果你使用的是yarn(较旧版本)来管理依赖库则运行:

?

yarn install big-integer --save

如果你使用的是yarn(新版本)来管理依赖则运行:

yarn add big-integer --save

后面为什么跟着--save自行查询文档,这里不做说明。

?二、库的使用

????????我项目使用生成的页面比较多,为了使用方便,我直接将添加到Vue的扩展方法中。

三、运行验证

文章来源:https://blog.csdn.net/yunhuaikong/article/details/135718332
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。