【问题标题】:Which functions could work as synchronous in node.js?哪些函数可以在 node.js 中同步工作?
【发布时间】:2017-02-10 22:08:12
【问题描述】:
例如,我正在编写一个带有crypto.randomBytes(...) 的随机生成器以及另一个异步函数。为了避免陷入回调地狱,我虽然可以使用crypto.randomBytes的同步功能。我的疑问是,如果我这样做,我的节点程序会在每次执行代码时停止?然后我想如果有一个运行时间很短的异步函数列表,它们可以作为同步函数工作,那么使用这个函数列表进行开发会很容易。
【问题讨论】:
标签:
node.js
asynchronous
concurrency
【解决方案1】:
使用mz 模块,您可以使crypto.randomBytes() 返回一个承诺。使用 await(在 Node 7.x 中使用 --harmony 标志可用),您可以像这样使用它:
let crypto = require('mz/crypto');
async function x() {
let bytes = await crypto.randomBytes(4);
console.log(bytes);
}
x();
上面是非阻塞,即使它看起来像是阻塞的。
要获得更好的演示,请考虑以下示例:
function timeout(time) {
return new Promise(res => setTimeout(res, time));
}
async function x() {
for (let i = 0; i < 10; i++) {
console.log('x', i);
await timeout(2000);
}
}
async function y() {
for (let i = 0; i < 10; i++) {
console.log('y', i);
await timeout(3000);
}
}
x();
y();
请注意,这两个函数需要很长时间才能执行,但它们不会相互阻塞。
使用 Node 7.x 运行它:
node --harmony script-name.js
或者在 Node 8.x 中使用:
node script-name.js
我向您展示这些示例是为了证明这不是选择异步与回调地狱并与漂亮的代码同步。实际上,您可以使用 ES2017 中提供的新的 async function 和 await 运算符以非常优雅的方式运行异步代码 - 阅读它很好,因为没有很多人知道这些功能。
【解决方案2】:
它们是异步的,学会处理它。
Promises 现在和未来 ES2017 的 await 和 async 将使您的生活更轻松。
Bluebirds promisifyAll 在处理任何标准 Node.js 回调 API 时都非常有用。它添加了带有Async 标记的函数,这些函数返回一个承诺而不是需要回调。
const Promise = require('bluebird')
const crypto = Promise.promisifyAll(require('crypto'))
function randomString() {
return crypto.randomBytesAsync(4).then(bytes => {
console.log('got bytes', bytes)
return bytes.toString('hex')
})
}
randomString()
.then(string => console.log('string is', string))
.catch(error => console.error(error))