2016-05-05 5 views
0

Verwenden von Node.js Ich muss drei Dateien dynamisch mit einer require() Funktion laden, indem Sie den Dateipfad von Cassandra abrufen. Von jeder Datei muss ich Daten holen, die in Redis sind, und eine Validierung durchführen, bevor ich eine andere Datei von Cassandra lade. Das Problem hier ist: Bevor die Validierungslogik ausgeführt wird und Ergebnisse liefert, wird der nächste Dateistart parallel geladen. Das Validierungsergebnis kommt nach dem Laden der zweiten Datei, was nicht passieren sollte. Das Laden der zweiten Datei sollte warten, bis die erste Dateivalidierungslogik abgeschlossen ist, und muss nur geladen werden, wenn das Validierungsergebnis erfolgreich ist. Bitte helfen Sie mir ... Wie kann ich pausieren oder warten, bis Redis die Abfrage in node.js beendet hat ???Nodejs, nicht warten auf Redis Abfrage abgeschlossen, bevor mit der Ausführung fortgesetzt

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 gleichen Inhalt wie

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; 
} 

Ausgang:

res:::undefined 
res::: 
res::: 
value from redis::test data here 
value::e043e7e68058c8a4cd686db38f01771bd7a04b8bb9a658d3cb40d0be45935094 
redisValue:: 
redata::true 
redisValue2 == test data here 
redisValue3 == hello world test data 

Antwort

2

Sie sagen, dass file2/3 "gleicher Inhalt", aber sie sind nicht in einem kritischen Bereich. In der Dokumentation von Per Bluebird für promisifyAll (siehe http://bluebirdjs.com/docs/api/promise.promisifyall.html) erstellt diese Funktion eine ...Async Version jeder Kernfunktion in dem Redis-Client. Sie rufen hmgetAsync in Ihrem ersten Fall, aber Sie rufen nur hmget in Ihren anderen an.

Dies ist wichtig, weil Sie ein asynchrones Muster, jedoch mit einer nicht-asynchronen Codestruktur verwenden. In Datei2/3 setzen Sie result1 in einen asynchronen Callback, aber geben Sie ihn unter jedem Aufruf zurück, bevor der Aufruf möglicherweise zurückgegeben wurde.

Sie haben zwei Möglichkeiten:

1:

module.exports = function(redisclient, callback){ 

Statt der Rückkehr: Sie file2/3/etc zu einem vollständig traditionellen Mustern, indem in einem Rückruf zusätzlich zum redis Client umwandeln können result1, würden Sie dann rufen Sie den Rückruf mit diesem Wert:

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

2: Sie konvertieren könnte file2/3/.. N Versprechen basiert zu sein, wobei in diesem Fall nicht wahr müssen promisifyAll(require(...)) sie - Sie können einfach require() ihnen. Ein solches Muster könnte wie folgt aussehen:

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

Dies ist ein viel einfacher und sauberer Option, und wenn Sie mit ihm weitermachen können Sie sehen, dass Sie könnte wahrscheinlich sogar beseitigen die require() und einfach tun, um die hmgetAsync in file1 mit entsprechenden Daten von Cassandra zurückgegeben. Aber es ist schwer zu wissen, ohne Ihre spezifischen Anwendungsanforderungen zu sehen. In jedem Fall sind Promise-basierte Muster im Allgemeinen viel kürzer und sauberer, aber nicht immer besser - es gibt einen moderaten Leistungsaufwand für deren Verwendung. Es ist dein Ruf, wohin du gehst - beides wird funktionieren.

+0

Ich habe versucht beide Möglichkeiten, Für Callback-Methode bekomme ich "Calback ist keine Funktion" und für die Verheißungsmethode bekomme ich '{" isFulfilled ": false," isRejected ": false} 'als Ergebnis. – Balaviswa

+0

Meine Antwort wurde umschrieben. Ich habe im ersten Block auf einen gemeinsamen NodeJS-Callback-Term 'cb' und im zweiten auf' Callback' referenziert. Sie müssten natürlich übereinstimmen. Ich habe es aktualisiert, um dies zu reflektieren. –

Verwandte Themen