如何使用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手冊


更多節點教程: