function generate(count) {
var founded = false,
_sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
str = '';
while(!founded) {
for(var i = 0; i < count; i++) {
str += _sym[parseInt(Math.random() * (_sym.length))];
}
base.getID(string, function(err, res) {
if(!res.length) {
founded = true; // How to do it?
}
});
}
return str;
}
如何设置一个变量值与数据库查询回调?我该怎么做呢?
安装NPM uuid包(来源:https://github.com/uuidjs/uuid):
npm install uuid
并在你的代码中使用它,例如ES6导入:
import { v4 as uuidv4, v6 as uuidv6 } from 'uuid';
uuidv4();
uuidv6();
或者使用CommonJS需要:
const {
v1: uuidv1,
v4: uuidv4,
} = require('uuid');
uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
For
我已经有一段时间没有使用node.js了,但我想我可能能帮上忙。
首先,在node中,你只有一个线程,并且应该使用回调。你的代码会发生什么,就是这个基础。getID查询将被排队等待执行,但while循环将继续作为繁忙循环毫无意义地运行。
你应该能够解决你的问题回调如下:
function generate(count, k) {
var _sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
var str = '';
for(var i = 0; i < count; i++) {
str += _sym[parseInt(Math.random() * (_sym.length))];
}
base.getID(str, function(err, res) {
if(!res.length) {
k(str) // use the continuation
} else generate(count, k) // otherwise, recurse on generate
});
}
并这样使用它
generate(10, function(uniqueId){
// have a uniqueId
})
我在2年左右没有编写任何node/js,也没有测试过这个,但基本思想应该保持不变——不要使用繁忙循环,并使用回调。您可能想看一下节点异步包。
如果有人需要加密强UUID,也有解决方案。
https://www.npmjs.com/package/generate-safe-id
npm install generate-safe-id
Why not UUIDs?
Random UUIDs (UUIDv4) do not have enough entropy to be universally
unique (ironic, eh?). Random UUIDs have only 122 bits of entropy,
which suggests that a duplicate will occur after only 2^61 IDs.
Additionally, some UUIDv4 implementations do not use a
cryptographically strong random number generator.
This library generates 240-bit IDs using the Node.js crypto RNG,
suggesting the first duplicate will occur after generating 2^120 IDs.
Based on the current energy production of the human race, this
threshold will be impossible to cross for the foreseeable future.
var generateSafeId = require('generate-safe-id');
var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
从YaroslavGaponov的答案延伸出来,最简单的实现就是使用Math.random()。
Math.random()
从数学上讲,分数在实空间[0,1]中相同的概率理论上为0。在node.js中,它的默认长度为16个小数,概率接近于0。这种实现还应该减少算术溢出,因为不执行任何操作。此外,与字符串相比,它的内存效率更高,因为小数占用的内存比字符串少。
我称之为“分数-唯一id”。
编写代码生成1,000,000个Math.random()数字,但无法找到任何重复的数字(至少对于默认的小数点为16)。参见下面的代码(如果有请提供反馈):
random_numbers = []
for (i = 0; i < 1000000; i++) {
random_numbers.push(Math.random());
//random_numbers.push(Math.random().toFixed(13)) //depends decimals default 16
}
if (i === 1000000) {
console.log("Before checking duplicate");
console.log(random_numbers.length);
console.log("After checking duplicate");
random_set = new Set(random_numbers); // Set removes duplicates
console.log([...random_set].length); // length is still the same after removing
}
安装uuid
npm install --save uuid
Uuid被更新,旧的导入
const uuid = require('uuid/v4');
不工作,我们现在应该使用这个导入
const {v4: uuid} = require('uuid');
把它作为一个函数来使用
const createdPlace = {
id: uuid(),
title,
description,
location: coordinates,
address,
creator
};
我的5美分:
const crypto = require('crypto');
const generateUuid = () => {
return [4, 2, 2, 2, 6] // or 8-4-4-4-12 in hex
.map(group => crypto.randomBytes(group).toString('hex'))
.join('-');
};
遗憾的是,Pono的字符串缺少连字符,所以它不符合uuid标准,这是我相信大多数人来这里的原因。
> generateUuid();
'143c8862-c212-ccf1-e74e-7c9afa78d871'
> generateUuid();
'4d02d4d6-4c0d-ea6b-849a-208b60bfb62e'
你可以使用urid包npm安装urid
import urid from 'urid';
urid(); // qRpky22nKJ4vkbFZ
阅读完整的文档:https://www.npmjs.com/package/urid
// Set the size
urid(8); //ZDJLC0Zq
// Use the character set
urid('num'); // 4629118294212196
urid('alpha'); // ebukmhyiagonmmbm
urid('alphanum'); // nh9glmi1ra83979b
// Use size with character set
urid(12, 'alpha'); // wwfkvpkevhbg
// use custom character set
urid(6, '0123456789ABCDEF'); // EC58F3
urid('0123456789ABCDEF'); // 6C11044E128FB44B
// some more samples
urid() // t8BUFCUipSEU4Ink
urid(24) // lHlr1pIzAUAOyn1soU8atLzJ
urid(8, 'num') // 12509986
urid(8, 'alpha') // ysapjylo
urid(8, 'alphanum') // jxecf9ad
// example of all character sets
urid('num') // 5722278852141945
urid('alpha') // fzhjrnrkyxralgpl
urid('alphanum') // l5o4kfnrhr2cj39w
urid('Alpha') // iLFVgxzzUFqxzZmr
urid('ALPHA') // ALGFUIJMZJILJCCI
urid('ALPHANUM') // 8KZYKY6RJWZ89OWH
urid('hex') // 330f726055e92c51
urid('HEX') // B3679A52C69723B1
// custom character set
urid('ABCD-') // ACA-B-DBADCD-DCA
这里是目前解决方案的一个基准,参考纳米基准
import { v4 as uuid4 } from 'uuid'
import benchmark from 'benchmark'
import shortid from 'shortid'
let suite = new benchmark.Suite()
suite
.add('crypto.randomUUID', () => {
crypto.randomUUID()
})
.add('nanoid', () => {
nanoid()
})
.add('uuid v4', () => {
uuid4()
})
.add("math.random", () => {
(new Date()).getTime().toString(36) + Math.random().toString(36).slice(2)
})
.add('crypto.randomBytes', () => {
crypto.randomBytes(32).toString('hex')
})
.add('shortid', () => {
shortid()
})
.on('cycle', event => {
let name = event.target.name
let hz = formatNumber(event.target.hz.toFixed(0)).padStart(10)
process.stdout.write(`${name}${pico.bold(hz)}${pico.dim(' ops/sec')}\n`)
})
.run()
结果是
node ./test/benchmark.js
crypto.randomUUID 13,281,440 ops/sec
nanoid 3,278,757 ops/sec
uuid v4 1,117,140 ops/sec
math.random 1,206,105 ops/sec
crypto.randomBytes 280,199 ops/sec
shortid 30,728 ops/sec
测试env:
2.6 GHz 6Cores Intel酷睿i7 MacOS
节点v16.17.0