一尘不染

用Node.js中的Promise替换回调

node.js

我有一个简单的节点模块,该模块连接到数据库,并且具有几个用于接收数据的功能,例如,以下功能:


dbConnection.js:

import mysql from 'mysql';

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'user',
  password: 'password',
  database: 'db'
});

export default {
  getUsers(callback) {
    connection.connect(() => {
      connection.query('SELECT * FROM Users', (err, result) => {
        if (!err){
          callback(result);
        }
      });
    });
  }
};

该模块将从另一个节点模块中以这种方式调用:


app.js:

import dbCon from './dbConnection.js';

dbCon.getUsers(console.log);

我想使用promise而不是回调以返回数据。到目前为止,我已经在以下线程中阅读了有关嵌套的Promise的内容:使用嵌套的Promises编写干净的代码,但是我找不到适合该用例的任何简单解决方案。result用承诺退货的正确方法是什么?


阅读 259

收藏
2020-07-07

共1个答案

一尘不染

使用Promise课程

我建议看一下MDN的Promise文档,它们为使用Promises提供了一个很好的起点。另外,我确定在线上会有很多教程。:)

注意: 现代浏览器已经支持Promises的ECMAScript 6规范(请参阅上面的MDN文档),并且我假设您要使用本机实现,而没有第三方库。

至于一个实际的例子…

基本原理如下:

  1. 您的API被称为
  2. 您创建一个新的Promise对象,该对象将单个函数用作构造函数参数
  3. 您提供的函数由基础实现调用,并且该函数具有两个函数- resolvereject
  4. 完成逻辑后,您可以调用其中之一来完全履行Promise或因错误而拒绝它

这看起来可能很多,所以这里是一个实际示例。

exports.getUsers = function getUsers () {
  // Return the Promise right away, unless you really need to
  // do something before you create a new Promise, but usually
  // this can go into the function below
  return new Promise((resolve, reject) => {
    // reject and resolve are functions provided by the Promise
    // implementation. Call only one of them.

    // Do your logic here - you can do WTF you want.:)
    connection.query('SELECT * FROM Users', (err, result) => {
      // PS. Fail fast! Handle errors first, then move to the
      // important stuff (that's a good practice at least)
      if (err) {
        // Reject the Promise with an error
        return reject(err)
      }

      // Resolve (or fulfill) the promise with data
      return resolve(result)
    })
  })
}

// Usage:
exports.getUsers()  // Returns a Promise!
  .then(users => {
    // Do stuff with users
  })
  .catch(err => {
    // handle errors
  })

使用异步/等待语言功能(Node.js> = 7.6)

在Node.js 7.6中,v8 JavaScript编译器已通过async /
await支持
进行了升级。现在,您可以将函数声明为is
async,这意味着它们会Promise在异步函数完成执行后自动返回一个已解析的。在此函数内,您可以使用await关键字等待另一个Promise解析。

这是一个例子:

exports.getUsers = async function getUsers() {
  // We are in an async function - this will return Promise
  // no matter what.

  // We can interact with other functions which return a
  // Promise very easily:
  const result = await connection.query('select * from users')

  // Interacting with callback-based APIs is a bit more
  // complicated but still very easy:
  const result2 = await new Promise((resolve, reject) => {
    connection.query('select * from users', (err, res) => {
      return void err ? reject(err) : resolve(res)
    })
  })
  // Returning a value will cause the promise to be resolved
  // with that value
  return result
}
2020-07-07