未处理拒绝错误:发送后无法设置标头。 Node.js的

时间:2017-07-15 09:55:25

标签: node.js promise

尝试在代码下方运行时,我得到未处理拒绝错误:发送后无法设置标头返回GetData(); 被调用时,它会开始执行函数但立即返回控件返回错误。在调试过程中观察。

基本上,如果redis DB中不存在,代码会尝试从MySQL DB中获取密钥

所有与数据库和redis相关的模块都写在单独的文件中,以便重复使用。

somefile.js

var express = require('express');
var router = express.Router();
var dbModules = require('../common/database');
var redisModules = require("../common/redismodule");

function getSettings(request, response) 
{
    return GetData();

    function GetData() 
    {
        return redisModules.GetRedisValue("key")
        .then(function (result) 
        {
            if (!result) 
                return SetData();      
            else 
                return result;
        })
        .then(function (result) 
        {
            response.status(200).send({ value : result });
        })
        .catch(function (e) 
        {
            response.status(500).send();
        };
    }

    function SetData()
    {
        return dbModules.executeQuery('query')
        .then(function(results) 
        {
            // some code
            return 'some_key';
        })
        .then(function (result) 
        {
            redisModules.setRedisValue('key', result);
        });
    }
}

database.js

用于处理数据库连接的文件

var mysql = require('promise-mysql');

pool = mysql.createPool({
  host: '',
  user: '',
  password: '',
  database: '',
  connectionLimit: 4
});


module.exports = {

  getSqlConnection: function()
  {
      return pool.getConnection().disposer(function(connection) 
      {
          console.log("came here in releasing connection function");
          pool.releaseConnection(connection);
      });
  },

  executeQuery: function(sqlQuery)
  {
      return Promise.using(module.exports.getSqlConnection(), function(connection) 
      {
          return connection.query(sqlQuery)
          .then(function(results) 
          {
              return results;
          });
      });
  }
};

redismodule.js

处理redis get的文件,设置概念

var Promise = require('bluebird');
var constants = require('../common/contants');

var redisClient;        // Global (Avoids Duplicate Connections)

module.exports = 
{
    OpenRedisConnection : function()
    {
        if (redisClient == null) 
        {
            redisClient = require("redis").createClient(6379, 'localhost');
        }
    },
    isRedisConnectionOpened : function()
    {
        if (redisClient && redisClient.connected == true) 
        {
            return true;
        }
        else 
        {
            if(redisClient)
                redisClient.end();  // End and open once more

            module.exports.OpenRedisConnection();
            return true;
        }
    },
    GetRedisValue: function (key) 
    {
        return new Promise(function (resolve, reject)
        {
            if(!module.exports.isRedisConnectionOpened())
                 reject("Redis connection failure");

            redisClient.get(key, function (error, result) 
            {
                if (error) 
                {
                    reject(error);
                }
                else 
                {
                    if (result == null)
                        resolve();    // Key not present so create
                    else
                        resolve(result);
                }
            });
        }); 
    },
    SetRedisValue: function (key, value) 
    {           
        return new Promise(function (resolve, reject)
        {
            if(!module.exports.isRedisConnectionOpened())
                 reject("Redis connection failure");

            redisClient.set(key, value, 'EX', 1000, 
            function(err,reply) 
            {
                if (reply == 'OK')
                    resolve(value);         // Send the value
                else
                    reject(err);
            });
        }); 
    }
};

执行getSettings函数时,执行开始。

我刚刚包含了所有代码,以便在正确的情况下对其他代码有用。

更正后的答案

somefile.js

var Promise = require('bluebird');
var dbModules = require('database');
var redisModules = Promise.promisifyAll(require("redismodule"));

async function getSettings(request, response) {

    try {
        var data = redisModules.GetRedisValue("key");
        if (!data)
            data = await SetData();

        return response.status(200).send({
            value: data
        });

    } catch (error) {
        return response.status(500).send({
            'error': 'Try after some time'
        });
    }    

    function SetData() {
        let result = dbModules.executeQuery('query')
        return redisModules.setRedisValue('key', result);
    }
}

database.js

var mysql = require('promise-mysql');
var pool = mysql.createPool({
    host: '',
    user: '',
    password: '',
    database: '',
    connectionLimit: 4
});

function getSqlConnection() {
    return pool.getConnection().disposer(function (connection) {
        console.log("came here in releasing connection function");
        pool.releaseConnection(connection);
    });
}

module.exports = {
    executeQuery: function (sqlQuery) {
        return Promise.using(getSqlConnection(), function (connection) {
            return connection.query(sqlQuery)
                .then(function (results) {
                    return results;
                });
        });
    }
};

redismodule.js

var redisClient; // Global (Avoids Duplicate Connections)

// Making the below functions are private
function openRedisConnection() {
    if (redisClient && redisClient.connected == true) {
        return;
    } else {
        if (redisClient)
            redisClient.end(); // End and open once more

        redisClient = require("redis").createClient(6379,
            process.env.REDIS_URL, {
                auth_pass: process.env.REDIS_PASS
            });
        redisClient.selected_db = 1;
    }
}

module.exports = {
    GetRedisValue: function (key) {
        openRedisConnection();

        redisClient.get(key, function (error, result) {
            if (error) {
                return error;
            } else {
                if (result)
                    return result;
                else
                    return null;
            }
        });
    },
    SetRedisValue: function (key, value) {

        openRedisConnection();

        redisClient.set(key, value, 'EX', 1000,
            function (err, reply) {
                if (reply == 'OK')
                    resolve(value); // Send the value
                else
                    reject(err);
            });
    }
};

1 个答案:

答案 0 :(得分:1)

这就是我看到它的方式:

<强> somefile.js

var dbModules = require('../common/database');
var redisModules = require("../common/redismodule");

function getSettings(request, response) {
    function getData() {
        return redisModules.getRedisValue('key')
        .then(function (result) {
            return result || setData();
        });
    }

    function setData() {
        return dbModules.executeQuery('query')
        .then(function(results) {
            return redisModules.setRedisValue('key', results);
        });
    }

    return getData()
    .then(function(result) {
        response.status(200).send({ value: result });
    }).catch(function (e) {
        response.status(500).send();
    });
}

<强> database.js

var mysql = require('promise-mysql');
var pool = mysql.createPool({
    host: '',
    user: '',
    password: '',
    database: '',
    connectionLimit: 4
});

function getSqlConnection() {
    return pool.getConnection().disposer(function(connection) {
        console.log("came here in releasing connection function");
        pool.releaseConnection(connection);
    });
}

module.exports = {
    'executeQuery': function(sqlQuery) {
        return Promise.using(getSqlConnection(), function(connection) {
            return connection.query(sqlQuery);
        });
    }
};

<强> redismodule.js

var Promise = require('bluebird');
var redis = Promise.promisifyAll(require('redis'));
var redisClient = null;

function openRedisConnection() {
    if (!redisClient || !redisClient.connected) {
        if (redisClient) {
            redisClient.end(); // End and open once more
        }
        redisClient = redis.createClient(6379, process.env.REDIS_URL, {
            auth_pass: process.env.REDIS_PASS
        });
        redisClient.selected_db = 1;
    }
    return redisClient;
}

module.exports = {
    'getRedisValue': function(key) {
        return openRedisConnection().getAsync(key); // here we call the promise-returning .getAsync() method, created by Promise.promisifyAll()
    },
    'setRedisValue': function(key, value) {
        return openRedisConnection().setAsync(key, value, 'EX', 1000); // here we call the promise-returning .setAsync() method, created by Promise.promisifyAll()
    }
};

我的主要贡献在somefile.jsredismodule.js。第三个模块database.js已被整理,但仅此而已。

dbModules.executeQuery('query')redisModules.getRedisValue('key')等问题需要解决,但我想你知道你在那里做了什么。