在 Node.JS 中使用 Bluebird Promises 进行 2 个异步操作

Using Bluebird Promises in Node.JS with 2 async operations

我有一个场景,我需要从 MySQL 数据库获取记录并在 redis 缓存中更新并关闭 MySQL 和 redis 连接。

步骤:

  1. 打开MySQL连接
  2. 成功时从 MySQL 数据库中获取记录
  3. 根据MySQL查询结果
  4. 成功更新Redis缓存
  5. 关闭 MySQL 数据库连接。

我正在尝试使用 Bluebird promises 但没有得到适当的结果。

下面代码中的问题是 done 最初被调用,甚至在本应最后执行的 processBreakingNewsData 函数中被调用。

有错误的地方请指正

下面是我的node.js代码

constants.js 文件

var Promise = require('bluebird');

module.exports = {
  getRedisConnection: function () {
    return require("redis").createClient(6379, 'XXXX', { auth_pass: 'XXXX' });
  },
  getMySqlConnection: function () {
    var conObj = { host: "localhost", user: "root", password: "", database: "deccan" };

    var connection = require("mysql").createConnection(conObj);

    return new Promise(function (resolve, reject) {
      connection.connect(function (error) { 
        if (error)
          reject(error);
        else
          resolve(connection);
      });
    });       
  }
};

testing.js 文件

var constants = require("./constants.js");
var Promise = require('bluebird');

constants.getMySqlConnection().then(processBreakingNewsData)
.catch(function (e) {
  console.log("Error : " + e);
}).done(function () {
  console.log("Finished");
});

function processBreakingNewsData(connection) {
  return new Promise(function (resolve, reject) {
    connection.query("select id, text, DATE_FORMAT(created_at, '%Y-%m-%d %H:%i:%s') as 'created_at' from breakingnews;", function (error, results) {
      connection.end();

      if (error)
        reject(error);
      else
        resolve(results);
    });

  }).then(function (results) {
    return new Promise(function (resolve, reject) {
      var value = "";

      if (results.length > 0)
        value = JSON.stringify(results);

      var client = constants.getRedisConnection();

      client.set("bnews", value, function (err, reply) {
        if (err)
          reject(new Error("Error during Update of BreakingNews : " + err));
        else
          resolve(reply);
      });
    });           
  }).catch(function (e) {
    console.log("Error during Update of BreakingNews : " + e);

  }).done(function (result) {
    console.log("Breaking News Updated in Redis.");
  });
}

这里有 2 个问题:

  1. then永远return一个承诺

.then 永远是 return 的承诺。如果您自己没有 return,则会使用 return 值创建已解决的承诺。这就是这里发生的事情:processBreakingNewsData 中的 .then 立即 return 是一个已解决的承诺,然后执行您完成的回调。

为避免这种情况,您需要明确地return一个持续的承诺:

function processBreakingNewsData(connection)
{
    return new Promise(function (resolve, reject) 
    {
        // ...
    }).then(function (results) 
    {
        return new Promise(function (resolve, reject) {
            // ...
  1. done 没有 return 承诺

您的最后一个 done 处理程序没有 return 承诺,这意味着整个 processBreakingNewsData 没有 return 承诺。因此,再次调用 then returns 立即解决承诺。

切勿使用 done。这是来自文档:

.done(
    [function(any value) fulfilledHandler],
    [function(any error) rejectedHandler]
) -> undefined 

The use of this method is heavily discouraged and it only exists for historical reasons.

您可以在这里安全地将 done 替换为 then,因为您事先发现了错误。