How to use promise and wait function based on Node.js callback

Most Node.js APIs were built in an era before their promises were fulfilled, and they used callback-based solutions.

The typical Node.js API works as follows:

doSomething(param, (err, result) => {

})

This also applies to libraries. An example isnode-redis, And when using it on a project, you really need to delete all callbacks, because I have too many levels of callbacks nested between each other-a perfect "callback hell" scenario.

In addition, sometimes it is absolutely necessary to avoid callbacks because you need to return the result of the function call from the function. If the result is returned in the callback, the only way to get the result is to use a function to send it back, and the callback party will continue:

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) })

There is a simple solution.

The solution provided by Node.js itself.

By importing, we can "promise" any function that does not support promise (so async / await syntax is not supported)promisifyFrom core Node.jsutilModule:

const { promisify } = require('util')

Then, we use it to create a new function:

const ahget = promisify(client.hget).bind(client)
const asmembers = promisify(client.smembers).bind(client)
const ahkeys = promisify(client.hkeys).bind(client)

See how i addaMeans lettersAsynchronous.

Now we can change this example to "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)
      })
    })
  })
})

Become cleaner:

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) })

This is the best choice when using features that you cannot access, for example in this case, I am using a third-party library.

At the bottom, promise wraps the function in a promise and returns it.

You can also do this manually, return a Promise from a function, and then use it with 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)

Download mine for freeNode.js manual


More node tutorials: