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;
}

如何设置一个变量值与数据库查询回调?我该怎么做呢?


当前回答

这里是目前解决方案的一个基准,参考纳米基准

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

其他回答

生成加密性强的伪随机数据。size参数是一个数字,表示要生成的字节数。

// Asynchronous
const {
  randomBytes,
} = require('crypto');

randomBytes(256, (err, buf) => {
  if (err) throw err;
  console.log(`${buf.length} bytes of random data: unique random ID ${buf.toString('hex')}`);
});

知道更多

编辑:shortid已弃用。维护者建议使用纳米体代替。


另一种方法是使用npm中的shortid包。

它非常容易使用:

var shortid = require('shortid');
console.log(shortid.generate()); // e.g. S1cudXAF

它有一些引人注目的特点:

ShortId创建惊人的短非顺序url友好的唯一 id。完美的url缩短器,MongoDB和Redis id,和任何其他 用户可能看到的Id。 默认7-14个url友好字符:A-Z, A-Z, 0-9, _- 非连续的,所以它们是不可预测的。 可以生成任意数量的id而不重复,甚至每天数百万。 应用程序可以重新启动任意次数,没有任何重复id的机会。

简单,基于时间,没有依赖:

(new Date()).getTime().toString(36)

or

Date.now().toString(36)

输出:jzlatihl


加上随机数(感谢@Yaroslav Gaponov的答案)

(new Date()).getTime().toString(36) + Math.random().toString(36).slice(2)

jzlavejjperpituute输出

我已经有一段时间没有使用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,也没有测试过这个,但基本思想应该保持不变——不要使用繁忙循环,并使用回调。您可能想看一下节点异步包。

这里的解决方案是旧的,现在已弃用:https://github.com/uuidjs/uuid#deep-requires-now-deprecated

用这个:

NPM安装uuid

//add these lines to your code
const { v4: uuidv4 } = require('uuid');
var your_uuid = uuidv4();
console.log(your_uuid);