我有一个场景,web服务需要检查redis中是否存在key,如果存在则将其作为响应提交,否则从mysql获取,存储在redis中然后将其作为响应。
所以我使用的是promises概念,当我第一次调用返回新的Set_Data(); 它没有进入下一个然后阻止它只是保持空闲状态。但是下次因为数据已经存在,返回新的Set_Data(); 没有执行是正确的。
但是为什么我第一次遇到问题时,我打电话给返回新的Set_Data(); ,这不是下一个阻止。
以下是我的代码
constants.js文件
var Promise = require('bluebird');
module.exports =
{
getRedisConnection: function ()
{
return require("redis").createClient(6379, 'path', { auth_pass: 'key' });
},
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);
});
});
}
};
webservicefile.js
var Promise = require('bluebird');
var express = require('express');
var router = express.Router();
var constants = require("../constants");
function getSettings(request, response)
{
var client = constants.getRedisConnection();
get_Data();
function get_Data()
{
return new Promise(function (resolve, reject)
{
client.get("url", function (error, reply)
{
if (error)
reject(error);
else
{
if (reply == null)
resolve(); // Key not present so create
else
resolve(reply);
}
});
}).
catch(function (e)
{
console.log("Error at : " + new Date().toString() + ", => " + e);
}).
then(function (urlResult)
{
return new Promise(function (resolve, reject)
{
if (urlResult == undefined || urlResult == null)
{
return new Set_Data();
}
else
{
client.quit();
return resolve(urlResult);
}
});
}).
then(function (urlResult)
{
if (urlResult)
response.status(200).send({ url : urlResult });
else
response.status(500).send();
})
}
function Set_Data()
{
constants.getMySqlConnection().then(function (connection)
{
return new Promise(function (resolve, reject)
{
connection.query("select url from table where id = 1", function (error, results)
{
connection.end();
if (error)
reject(error);
else
resolve(results);
});
});
}).
then(function (url)
{
return new Promise(function (resolve, reject)
{
client.set('url', url, function (err, reply)
{
if (err)
reject(err);
else
resolve(url);
});
});
});
}
}
答案 0 :(得分:1)
如果没有urlResult,你可以直接返回新的Set_Data(),否则返回urlResult - 在then
内返回的任何(非Promise)值是已解析的Promise - 所以.then
链将继续按要求
function get_Data() {
// ...
.then(function (urlResult) {
// you don't need a "new Promise" here
if (urlResult == undefined || urlResult == null) {
return new Set_Data();
} else {
client.quit();
return urlResult;
}
})
// ...
}
我在代码中注意到的一件事是.catch
链中间的.then
,它会将错误有效地转化为履行承诺 - 不确定这是否属于您的行为正在找。
答案 1 :(得分:1)
一些变化应该可以解决问题,首先Set_Data()
不会像您认为的那样返回承诺,添加return
:
function Set_Data() {
return constants.getMySqlConnection().then(function (connection).then()
// ...
}
在这个回调中,你在if中没有resolve()
,承诺永远不会被解决,返回的东西无法解决:
// your code
then(function (urlResult) {
return new Promise(function (resolve, reject) {
if (urlResult == undefined || urlResult == null) {
return new Set_Data();
} else {
client.quit();
return resolve(urlResult);
}
});
}).
返回现在是承诺的Set_Data()
或网址:
then(function (urlResult) {
if (urlResult == undefined || urlResult == null) {
return new Set_Data();
} else {
client.quit();
return urlResult;
}
}).
在旁注中,不要像C#那样格式化你的js代码,{
不应该在新行上。