我正在构建一个使用async/await
的库,我想知道是否可以使用像fs
这样的本地模块和async/await
。我知道async/await
它只是背景中的Promise,所以有一种本地方式来宣传方法或功能吗?目前我正在使用蓝鸟,但我不知道这是不是一个糟糕的模式。
例:
const Bluebird = require("bluebird");
const { access } = require("fs");
const accessAsync = Bluebird.promisify(access);
async function checkInput(options) {
await accessAsync(options.file);
/// etc
return options;
}
module.exports = (options) => {
Promise.resolve(options)
.then(checkInput)
};
我正在结合原生的Promises和Bluebird。我应该只使用蓝鸟吗?
我正在构建一个使用async / await的库,我想知道是否可以使用ass / await这样的本机模块。
是。使用Bluebird比使用示例更简单:
let fs = Promise.promisifyAll(require('fs'));
// and in async function:
let contents = await fs.readFileAsync('file.txt', 'utf-8');
请注意,您需要在方法名称的末尾添加Async
。
或者您可以使用mz
模块,而无需将Async
添加到方法中。看到:
一旦你npm install mz
,你可以要求许多模块 - 例如你可以require('mz/fs')
,它立即让你使用返回promises而不是回调的fs
模块版本。结合异步等待它可以让你做以下事情:
let fs = require('mz/fs');
// and in async function:
let contents = await fs.readFile('file.txt', 'utf-8');
上面的代码仍然是非阻塞的。
请参阅此答案,其中我展示了mz
模块的crypto
版本的示例并更详细地解释它:
见例子:
let crypto = require('mz/crypto');
async function x() {
let bytes = await crypto.randomBytes(4);
console.log(bytes);
}
您可以对许多其他模块执行相同的操作,包括:
child_process
crypto
dns
fs
readline
zlib
我知道async /等待它只是背景中的Promise,所以......是否有一种本地方式来宣传方法或功能?
不久Node将本地支持 - 请参阅PR#5020为Promises添加核心支持:
但在此期间你可以使用mz
。
有关更多上下文,请参阅问题#7549 v1:执行没有回调的异步函数应该返回promises:
另请参阅Node的Promises工作组存储库:
更新:似乎上面提到的PR 5020不会很快降落在Node中 - 感谢Benjamin Gruenbaum在评论中指出它。所以似乎使用Bluebird的promisify
和promisifyAll
以及有用的mz
模块将是使用Node的核心模块使用该语言的现代功能的唯一简单方法。幸运的是,它们运作良好,所以这不是一个大问题。
使用Bluebird和Promises只会增加你的头脑。意味着蓝鸟足以处理其他承诺。
谢谢
无论如何,bluebird旨在与本机承诺一起使用。您描述的用例不仅受支持 - 而且是Bluebird的设计目标。
Bluebird的承诺根据Promises / A +规范实施then
,保证与await
一起使用。更重要的是,你可以将原生承诺传递给蓝鸟,它会工作得很好。