使用Node.js我需要通过从Cassandra获取文件路径,使用require()
函数动态加载三个文件。从每个文件中我需要获取Redis中的数据并在从Cassandra加载另一个文件之前进行一些验证。这里的问题是:在验证逻辑执行并提供结果之前,下一个文件开始并行加载。验证结果在加载第二个文件之后出现,这不应该发生。第二个文件加载应该等待第一个文件验证逻辑完成,并且只有在验证结果成功时才必须加载。请帮帮我...如何暂停或等待Redis在node.js ???
node.js
"use strict";
var express = require('express');
var cassandra = require('cassandra-driver');
var app = express();
var Promise = require('bluebird');
var redis = Promise.promisifyAll(require('redis'));
var redisClient = redis.createClient(6379, '127.0.0.1');
var client = new cassandra.Client({contactPoints: ['127.0.0.1'], keyspace: 'poc'});
client.execute("SELECT file FROM testqry1", function (err, result) {
if (!err){
if ( result.rows.length > 0 ) {
for(var i=0; i< result.rows.length; i++){
var filePath=result.rows[i].get('file');
var newdat=Promise.promisifyAll(require(filePath));
var res = newdat(redisClient);
console.log('res:::'+res);
if (res=='failed'){
return;
}
}
} else {
console.log("No results");
}
}
});
file1.js
var crypto = require('crypto');
var redisValue='';
module.exports = function(redisclient){
redisclient.hmgetAsync("testdata", "text1").then(function(redisValue){
console.log('value from redis::'+redisValue)
}).then(function(){
var hashedUserID = crypto.createHmac('sha256', 'sample')
.update('helloworld')
.digest('hex');
function disp(value) {
console.log('value::'+value);
}
disp(hashedUserID);
console.log('redisValue::'+redisValue);
if(hashedUserID =='e043e7e68058c8a4cd686db38f01771bd7a04b8bb9a658d3cb40d0be45935094'){
redata='true';
}else{
redata='false';
}
console.log('redata::'+redata)
})
}
file2.js&amp; file3.js作为相同的内容
var result1='';
module.exports = function(redisclient){
redisclient.hmget("testdata", "text1" , function(err, redisValue){
console.log('redisValue2 == %s',redisValue);
if(redisValue == 'test value'){
result1 = "success";
}else{
result1="failed";
}
});
return result1;
}
输出:
res:::undefined
res:::
res:::
value from redis::test data here
value::e043e7e68058c8a4cd686db38f01771bd7a04b8bb9a658d3cb40d0be45935094
redisValue::
redata::true
redisValue2 == test data here
redisValue3 == hello world test data
答案 0 :(得分:2)
你说file2 / 3是“相同内容”但它们不在一个关键区域。根据Bluebird的promisifyAll
文档(请参阅http://bluebirdjs.com/docs/api/promise.promisifyall.html),此功能会在Redis客户端中为每个核心功能创建...Async
版本。您在第一种情况下致电hmgetAsync
,但只能在其他人中拨打hmget
。
这很重要,因为您使用的是异步模式,但具有非异步代码结构。在file2 / 3中,你在异步回调中设置result1
,但是在调用可能已经返回之前,在每个调用之后返回它。
您有两种选择:
1:除了redis客户端之外,您还可以通过传递回调将file2 / 3 / etc转换为完全传统的模式:
module.exports = function(redisclient, callback){
然后,您将使用此值调用回调,而不是返回result1
:
if(redisValue == 'test value'){
callback(null, "success");
} else {
callback("failed", null);
}
2:您可以将file2 / 3 / .. N转换为基于Promise的,在这种情况下,您不需要promisifyAll(require(...))
它们 - 您可以简单地require()
它们。这样的模式可能看起来像:
module.exports = function(redisclient){
return redisclient.hmgetAsync("testdata", "text1");
};
这是一个更简单,更简洁的选项,如果你继续使用它,你可以看到你甚至可以消除require(),只需使用Cassandra返回的相应数据在file1中执行hmgetAsync
。但是,如果不了解您的具体应用需求,很难知道。无论如何,基于Promise的模式通常更短更清晰,但并不总是更好 - 使用它们的性能开销适中。这是你打电话的方式 - 要么会奏效。