我有一个简单的 node 模块,它连接到数据库,并具有多个接收数据的功能,例如:


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

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


app.js:

import dbCon from './dbConnection.js';

dbCon.getUsers(console.log);

我希望使用promise 而不是回调来返回数据.

推荐答案

Using the Promise class

我建议看一看MDN's Promise docs,它为使用promise 提供了一个很好的起点.或者,我相信网上有很多教程.:)

Note:款现代浏览器已经支持ECMAScript 6promise 规范(参见上面链接的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 support.现在可以将函数声明为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
}

Node.js相关问答推荐

从目录中获取所有文件,而不是NodeJS中的单个文件

Firebase-admin筛选器.或只考虑第一个WHERE子句

已知NPM无法在node.js V12上运行的问题

Mongoose查询-如何根据当前查找ID获取其他集合并将其插入到当前查找中?

遇到 - TypeError:try 使用 Express(Node.js) 从 JSON 文件访问数据时无法读取未定义的属性(读取帖子)

错误:无法为 /blog 收集页面数据并且在 object.fetch 处获取失败

MongoDB - 查找查询以判断是否存在少量字段,结合字段上的 AND

使用 fs.createWriteStream 将数据写入 bigquery (node.js) 时出现模式错误

无法使用 node 预签名 url 从 React 将图像文件上传到 s3

为什么 $or 在带有正则表达式的mongoose 中不能正常工作

更新文档数组中的文档 Mongoose

NestJS TypeORM 可选查询不起作用

使用 nvm-windows 时更新 npm

Chrome 浏览器未将 if-modified-since 标头发送到服务器

编写可维护的事件驱动代码

如何运行用 TypeScript 编写的 Mocha 测试?

npm 出现无法读取依赖项错误

从 zip 文件在 AWS 中创建 lambda 函数

AWS Lambda 函数写入 S3

Npm postinstall 仅用于开发