2017-07-17 84 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