在 Node.JS 中使用 Bluebird Promises 进行 2 个异步操作
Using Bluebird Promises in Node.JS with 2 async operations
我有一个场景,我需要从 MySQL 数据库获取记录并在 redis 缓存中更新并关闭 MySQL 和 redis 连接。
步骤:
- 打开MySQL连接
- 成功时从 MySQL 数据库中获取记录
- 根据MySQL查询结果
成功更新Redis缓存
- 关闭 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 个问题:
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) {
// ...
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
,因为您事先发现了错误。
我有一个场景,我需要从 MySQL 数据库获取记录并在 redis 缓存中更新并关闭 MySQL 和 redis 连接。
步骤:
- 打开MySQL连接
- 成功时从 MySQL 数据库中获取记录
- 根据MySQL查询结果 成功更新Redis缓存
- 关闭 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 个问题:
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) {
// ...
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
,因为您事先发现了错误。