2017-07-17 53 views
1

我想刷新redis缓存数据库并返回状态的响应。但在清除缓存之前,它会返回响应。异步等待node.js不工作在节点v8.1.0

在下面的代码中,console.log将始终打印未定义,因为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; 
     });   
    } 
}; 

请帮我解决这个问题。

+0

不能使用'与节点样式的回调await'。它只适用于承诺。 –

+0

你能帮我转换flushRedisDB函数来使用承诺的概念,使其工作。 – Sharath

+0

@YuryTarabanko等待redisClient.flushall应该等待吗? – Sharath

回答

3

异步/等待只适用于承诺(如评论中所述)。所以,只需将您的回调包装到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相关方法的问题。

+0

请注意,在某些情况下,如果函数依赖于它的上下文,那么可能必须将函数绑定到它所连接的对象。 'cbToPromise(redisClient.flushall.bind(redisClient));' – Cobaltway

4

async/await只承诺工作所以这段代码不会等待回调

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

您需要promisify flushall方法。根据Docs它总是成功。

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

const flushed = await flusall() 

BTW。有内置节点^ v8的函数util.promisify,可以提供节点类型的cps函数。但它不会像这样处理总是成功的函数,所以你需要提供一个自定义的实现来工作。关于util.promisify

+0

可能在另一种情况下,如果有错误和成功? – Sharath

+0

@Sharath如果我正确理解你,那么'util.promisify'应该可以工作。 –

+0

好的,谢谢你得到了 – Sharath

0

蓝鸟提供了自己的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); 

一旦promisified可以使用异步/ AWAIT你的心脏的内容

+0

好的谢谢..... – Sharath