Node.js在then块中if else条件期间保证概念

时间:2015-12-25 19:30:18

标签: mysql node.js redis promise

我有一个场景,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);
                });
            });

        });
    }
}

2 个答案:

答案 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代码,{不应该在新行上。