2016-05-05 5 views
0

Node.jsを使用する私はCassandraからファイルパスを取得することによって、require()関数で動的に3つのファイルをロードする必要があります。各ファイルから、私はRedisにあるデータを取得し、Cassandraから別のファイルをロードする前に検証を行う必要があります。ここでの問題は、検証ロジックが実行されて結果を提供する前に、次のファイルの開始が並行して開始されることです。検証結果は2番目のファイルのロード後に発生しますが、これは発生しません。 2番目のファイルロードは、最初のファイル検証ロジックが完了するのを待つ必要があり、検証結果が成功した場合にのみロードする必要があります。私を助けてください...どのように私は一時停止するか、Redisはnode.jsでクエリを完了するのを待つのですか?Nodejs、実行を続行する前にRedisクエリが完了するのを待っていない

の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同じコンテンツとして& 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 

答えて

2

あなたはFILE2/3は "同じ内容" ですが、彼らは1つの重要なエリアではないことを言います。 Per BluebirdのpromisifyAllhttp://bluebirdjs.com/docs/api/promise.promisifyall.htmlを参照)のドキュメントでは、この機能はRedisクライアントに各コア機能の...Asyncバージョンを作成します。最初のケースではhmgetAsyncに電話しますが、他のケースではhmgetに電話するだけです。

これは、非同期パターンを使用しているが非同期コード構造を使用しているため、これは重要です。 file2/3では、非同期コールバック内にresult1を設定しますが、呼び出しが戻ってくる可能性がある前に、各呼び出しの下でそれを返します。

1:

次の2つの選択肢があり

module.exports = function(redisclient, callback){ 

の代わりに戻って:あなたはRedisのクライアントに加えて、コールバックに渡すことによってファイル2/3 /など、完全に伝統的なパターンに変換することができますresult1、あなたは、この値でコールバックを呼び出します。

if(redisValue == 'test value'){ 
    callback(null, "success"); 
} else { 
    callback("failed", null); 
} 

2:あなたは約束をベースとするファイル2/3/.. Nを変換することができ、あなたがそうでない場合にはpromisifyAll(require(...))にする必要があります - あなたは単にrequire()することができます。これは、はるかに簡単かつクリーンなオプションで、あなたはそれを続けるならば、あなたはおそらく必要()を排除し、単にFILE1にhmgetAsyncを行うことができていることがわかります

module.exports = function(redisclient){ 
    return redisclient.hmgetAsync("testdata", "text1"); 
}; 

:このようなパターンは次のようになります適切なデータがCassandraによって返されます。しかし、あなたの特定のアプリケーションニーズを見ずに知るのは難しいです。いずれにしても、プロミスベースのパターンは一般的にははるかに短く、よりクリーンですが、必ずしも良好ではありません。それは、あなたの行くところでのあなたの呼び出しです。どちらもうまくいきます。

+0

私は両方の選択肢を試しました。コールバックメソッドのために私は "calbackは関数ではありません"と約束しているメソッドのために '{" isFulfilled ":false、" isRejected ":false} ''という結果を得ています。 – Balaviswa

+0

私の答えは言い換えられました。最初のブロックで共通のNodeJSコールバック用語 'cb'を参照し、2番目のブロックで' callback'を参照しました。彼らは明らかに一致する必要があります。これを反映するように更新しました。 –

関連する問題