用 util.promisify 模拟 bluebird.promisifyAll
Posted
技术标签:
【中文标题】用 util.promisify 模拟 bluebird.promisifyAll【英文标题】:Emulating bluebird.promisifyAll with util.promisify 【发布时间】:2018-01-15 21:41:22 【问题描述】:我正在尝试使用 Node 8 的 util.promisify
以类似于 Bluebird 的 promisifyAll()
的工作方式来承诺整个 node_redis RedisClient
对象,但运气不佳。
这是我迄今为止尝试过的:
import * as _redis from 'redis';
import promisify from 'util';
const client = _redis.createClient();
const redis = Object.keys(client).reduce((c, key) =>
if (typeof c[key] === 'function') c[key] = promisify(c[key]).bind(c);
return c;
, client);
但是,这有效:
const redis =
get: promisify(client.get).bind(client),
set: promisify(client.set).bind(client),
hget: promisify(client.hget).bind(client),
hmset: promisify(client.hmset).bind(client),
;
有什么想法吗?
编辑: 我想使用 util.promisify
而不是像 Bluebird 这样的东西的主要原因是因为我在 TypeScript 中做这一切,而 Bluebird 的 promisifyAll
似乎没有使用它。
【问题讨论】:
这应该有助于grizzlybit.info/2017/09/29/Node-JS-8-Util-Promisify @zubair1024 它没有,你的博客文章与我的实际问题无关。 ?????? 这是一个使用util.promisify()
的promisifyAll()
的实现:npmjs.com/package/util-promisifyall
【参考方案1】:
您可以使用fluentify,它很小,没有外部依赖项,几乎可以满足您的需求。我实际上已经将它自己用于 Redis,有一些小警告,但在你的情况下应该相当简单,例如
import * as _redis from 'redis';
import fluentify from 'fluentifyjs';
...
const client = fluentify(_redis.createClient());
const result = await client.get('key').done();
我知道您可能希望在本地执行此操作,但是,考虑到如果需要,您可以免费获得方法链接,因此认为作为替代方案值得一提。
免责声明 - 我是作者
【讨论】:
它在 TypeScript 中能用吗?在拥有定义文件和能够将函数签名传回智能感知方面?我想使用本机 util.promisify 的一个重要原因是它可以很好地与 TypeScript 配合使用。 @aendrew 不幸的是没有,尽管添加支持不会太难。认为 lib 只需要添加定义文件,我不使用 TypeScript,所以目前还不能这样做。如果您愿意添加支持,请随时创建 PR。【参考方案2】:我在寻找同样的东西时遇到了这个。这是我目前正在使用的,它似乎工作:
const promisify = require('util')
const redis = require('redis')
const client = redis.createClient('redis://localhost:6379')
client.promise = Object.entries(redis.RedisClient.prototype)
.filter(([_, value]) => typeof value === 'function')
.reduce((acc, [key, value]) => (
...acc,
[key]: promisify(value).bind(client)
), )
client.on('connect', async () =>
await client.promise.set('foo', 'bar')
console.log(await client.promise.get('foo'))
)
【讨论】:
这很好用,但对于任何使用 typescript 的人来说都是一个小补充:将过滤器和 reduce 组合成这样的东西:reduce((acc, [key, val]) => (typeof val === 'function' ? ( ...acc, [key]: promisify(val).bind(client) ) : acc), )
。否则 typescript 对promisify(value)
不满意。
你还需要对类型进行一些时髦的玩弄,我最终得到了一个接口文件,它重新实现了许多 Redis 类型(在此处找到 github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/… )以使它们返回承诺。【参考方案3】:
我尝试了以下模块,它使用起来非常简单,可以用来替换 bluebird promises。 link
https://www.npmjs.com/package/util-promisifyall
【讨论】:
以上是关于用 util.promisify 模拟 bluebird.promisifyAll的主要内容,如果未能解决你的问题,请参考以下文章
将 node-redis 与 node 8 util.promisify 一起使用
_util.default.promisify不是使用Node 9.5的函数
Promise--实践练习之fs模块 & node运行Js脚本 & Promise封装练习-fs模块 & util.promisify方法