node.js中的异步等待在节点v8.1.0中不起作用

时间:2017-07-17 07:24:19

标签: node.js asynchronous async-await

我正在尝试刷新redis缓存db并返回响应中的状态。但在清除缓存之前,它会返回响应。

在下面的代码中,console.log将始终打印undefined,因为不等待flushRedisDB。

我的节点版本是v8.1.0

myfile.js

async function flushRedisapi(request, response)
{
    try {
        var value = await redisModules.flushRedisDB();
        console.log("the value is : " + value);
        if(value)
            response.status(200).send({status : 'Redis Cache Cleared'});
        else
            response.status(400).send({status : "Redis Cache could not be flushed"});

    } catch (error) {
        response.status(400).send({status : "Redis Cache could not be flushed"});
    }
}

redismodule.js

var redisClient;        // Global (Avoids Duplicate Connections)

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

            module.exports.openRedisConnection();

            return true;
        }
    },    
    flushRedisDB: async function()
    {
        if(!module.exports.isRedisConnectionOpened())
            return false;

        await redisClient.flushall(function (err, result) 
        {
            return (result == 'OK') ? true : false;
        });        
    }
};

请帮我解决这个问题。

3 个答案:

答案 0 :(得分:5)

Async / await仅适用于promises(如评论中所述)。所以只需将你的回调包装成Promise。

function cbToPromise(asyncFunc, ...params) {
    return new Promise((resolve, reject) => {
        asyncFunc(...params, (err, result) => {
            if (err) reject(err);
            else resolve(result);
        });
    });
};

try {
    const result = await cbToPromise(redisClient.flushall);
    return result == 'OK';
}
catch(err) {
    console.error(err);
} 

<强>附录:

仅当回调的签名为function(err, result)时才会起作用。根据另一个答案,情况并非如此(没有错误作为第一个参数传递),因为它永远不会失败。所以在这种情况下只需删除err参数,拒绝和try / catch处理程序。

为了方便起见,我在这里给出了答案,因为它很可能会帮助您解决其他与Redis相关的方法。

答案 1 :(得分:5)

async/await仅适用于承诺,因此此代码不会等待回调

    await redisClient.flushall(function (err, result) 
    {
        return (result == 'OK') ? true : false;
    }); 

您需要宣传flushall方法。根据{{​​3}},它总是成功。

 const flushall = () => new Promise(resolve => redisClient.flushall(resolve))

 const flushed = await flusall()

顺便说一句。有util.promisify函数内置节点^ v8,允许统一节点样式cps函数。但它不会处理这样的功能,所以你需要提供一个自定义的实现工作。关于Docs

答案 2 :(得分:0)

Bluebird提供自己的promisification,promisify all redis functions允许您只需将Async附加到您想要使用的任何redis命令。在您的情况下,它看起来像flushallAsync

const redis = require('redis');
const bluebird = require('bluebird');

bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);

一旦被宣传,您可以使用async / await到您心中的内容