大多数Node.js API都是在尚未实现诺言的时代构建的,它们使用了基于回调的解决方案。
典型的Node.js API的工作方式如下:
doSomething(param, (err, result) => {
})
这也适用于库。一个例子是node-redis
,并且在一个项目上使用它时,确实确实需要删除所有回调,因为我彼此之间嵌套了太多级别的回调-一个完美的“回调地狱”场景。
另外,有时绝对有必要避免回调,因为您需要从函数返回函数调用的结果。如果在回调中返回了该结果,则获取结果的唯一方法是使用一个函数将其发送回去,并且回调方将继续:
const myFunction = () => {
doSomething(param, (err, result) => {
return result //can't return this from `myFunction`
})
}
const myFunction = callback => {
doSomething(param, (err, result) => {
callback(result) //no
})
}
myFunction(result => {
console.log(result)
})
有一个简单的解决方案。
Node.js本身提供的解决方案。
通过导入,我们可以“承诺化”不支持promise的任何功能(因此不支持async / await语法)promisify
来自核心Node.jsutil
模块:
const { promisify } = require('util')
然后,我们使用它创建新函数:
const ahget = promisify(client.hget).bind(client)
const asmembers = promisify(client.smembers).bind(client)
const ahkeys = promisify(client.hkeys).bind(client)
看看我如何添加a
意思是字母异步的。
现在我们可以将这个示例更改为“ callback hell”:
client.hget(`user:${req.session.userid}`, 'username', (err, currentUserName) => {
client.smembers(`followers:${currentUserName}`, (err, followers) => {
client.hkeys('users', (err, users) => {
res.render('dashboard', {
users: users.filter((user) => user !== currentUserName && followers.indexOf(user) === -1)
})
})
})
})
变得更加干净:
const currentUserName = await ahget(`user:${req.session.userid}`, 'username')
const followers = await asmembers(`followers:${currentUserName}`)
const users = await ahkeys('users')
res.render(‘dashboard’, {
users: users.filter((user) => user !== currentUserName && followers.indexOf(user) === -1)
})
当使用您无法访问的功能时,这是最佳选择,例如在这种情况下,我使用的是第三方库。
在底层,promisify将函数包装在一个promise中,并返回它。
您也可以手动执行此操作,从一个函数返回一个Promise,然后将其与async / await一起使用:
const handleLogin = (req, user) => {
return new Promise((resolve, reject) => {
req.login(user, (err) => {
if (err) {
return reject({
error: true,
message: err,
})
}
return resolve({
success: true,
})
})
})
}
//…
const resultLogin = await handleLogin(req, user)
免费下载我的Node.js手册
更多节点教程:
- npm软件包管理器简介
- Node.js简介
- 使用Axios的HTTP请求
- 在哪里托管Node.js应用
- 使用Node.js与Google Analytics(分析)API进行交互
- npx节点包运行器
- package.json指南
- npm在哪里安装软件包?
- 如何更新Node.js
- 如何使用或执行使用npm安装的软件包
- package-lock.json文件
- 使用npm的语义版本控制
- 您是否应该将node_modules文件夹提交到Git?
- 将所有Node依赖项更新到最新版本
- 使用Node.js解析JSON
- 查找npm软件包的安装版本
- Node.js流
- 安装较旧版本的npm软件包
- 在Node中获取当前文件夹
- 如何在Node中记录对象
- 使用导出从Node文件公开功能
- 节点和浏览器之间的区别
- 使用Node发出HTTP POST请求
- 使用Node获取HTTP请求主体数据
- 节点缓冲区
- Node.js的简要历史
- 如何安装Node.js
- 使用Node您需要知道多少JavaScript?
- 如何使用Node.js REPL
- 节点,从命令行接受参数
- 使用Node输出到命令行
- 接受来自Node中命令行的输入
- 使用`npm uninstall`来卸载npm软件包。
- npm全局或本地软件包
- npm依赖项和devDependencies
- Node.js事件循环
- 了解process.nextTick()
- 了解setImmediate()
- 节点事件发射器
- 建立一个HTTP服务器
- 使用Node发出HTTP请求
- Node fs模块
- 使用Axios的Node中的HTTP请求
- 使用Node读取文件
- 节点文件路径
- 用Node写入文件
- 节点文件统计
- 在Node中使用文件描述符
- 在Node中使用文件夹
- 节点路径模块
- Node http模块
- 将WebSockets与Node.js结合使用
- 使用MySQL和Node的基础知识
- Node.js中的错误处理
- 哈巴狗指南
- 如何从Node.js读取环境变量
- 如何从Node.js程序退出
- Node os模块
- 节点事件模块
- 节点,开发与生产之间的区别
- 如何检查Node.js中是否存在文件
- 如何在Node.js中创建一个空文件
- 如何使用Node.js删除文件
- 如何使用Node.js获取文件的最后更新日期
- 如何在JavaScript中确定日期是否为今天
- 如何将JSON对象写入Node.js中的文件
- 为什么要在下一个项目中使用Node.js?
- 从任何文件夹运行Web服务器
- 如何将MongoDB与Node.js结合使用
- 使用Chrome DevTools调试Node.js应用
- 什么是pnpm?
- Node.js运行时v8选项列表
- 使用npm时如何解决“缺少写访问权限”错误
- 如何在Node.js中启用ES模块
- 如何使用Node.js生成子进程
- 如何在Express中同时获取已解析的正文和原始正文
- 如何在Node.js中处理文件上传
- 节点模块中的对等依赖性是什么?
- 如何使用Node.js编写CSV文件
- 如何使用Node.js读取CSV文件
- 节点核心模块
- 使用Node.js一次增加多个文件夹的数量
- 如何将画布打印到数据URL
- 如何使用Node.js和Canvas创建和保存图像
- 如何使用Node.js下载图像
- 如何在Node.js中批量重命名文件
- 如何获取Node中文件夹中所有文件的名称
- 如何使用Promise和基于Node.js回调的等待功能
- 如何在本地测试NPM软件包
- 如何在运行时检查当前的Node.js版本
- 如何使用Sequelize与PostgreSQL交互
- 使用Node.js服务HTML页面
- 如何解决Node.js中的util.pump不是函数错误