如何使用Promise和基于Node.js回调的等待功能

大多数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手册


更多节点教程: