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

Sha*_*ath 3 asynchronous node.js async-await

我正在尝试刷新Redis缓存数据库并在响应中返回状态。但是在清除缓存之前,它会返回响应。

在下面的代码中,由于不等待flushRedisDB,console.log将始终显示未定义的内容。

我的节点版本是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"});
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
        });        
    }
};
Run Code Online (Sandbox Code Playgroud)

请帮助我解决这个问题。

Cob*_*way 6

异步/等待仅适用于诺言(如评论中所述)。因此,只需将您的回调包装到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);
} 
Run Code Online (Sandbox Code Playgroud)

附录:

仅当回调的签名为时才有效function(err, result)。根据另一个答案,情况并非如此(没有错误作为第一个参数传递),因为它永远不会失败。因此,在这种情况下,只需剥离err参数,拒绝并尝试/捕获处理程序即可。

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


Yur*_*nko 5

async/await 仅与promise一起使用,因此此代码不等待回调

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

您需要承诺flushall方法。根据Docs的说法,它总是成功的。

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

 const flushed = await flusall()
Run Code Online (Sandbox Code Playgroud)

顺便说一句。有util.promisify内置的函数^ v8,它可以保证节点样式cps函数的正确性。但是它不会处理总是这样的后继功能,因此您需要提供一个自定义实现才能正常工作。关于util.promisify