2016-09-26 1 views
1

Ich bin neu in Knoten und blieb bei der Behandlung von mehreren asynchronen Aufgaben stecken.Knoten js - wie man mehrere asynchrone Aufgaben behandelt

Abgesehen von Knoten, ich habe einen anderen Server (S1), die Daten nicht sofort an Anfragen zurückgibt, kann es mehrere Arten von Daten zurückgeben und auch Benachrichtigungen senden, ohne sie speziell anfragen, so Knoten haben zu hören Daten von ihm, analysieren Sie es und handeln Sie entsprechend.

S1 = net.createConnection({'host':S1Host, 'port': S1Port}); 

Und Knoten hört Daten mit:

Die Verbindung zu diesem Server (S1) unter Verwendung erfolgt

S1.on('data', function(data){ 
    S1DataParse(data); 
}); 

ich die richtigen Daten zur Strecke haben (nach dem Parsen es) zu einer bestimmten POST-Anfrage.

Ich habe versucht, das Async-Modul dafür zu verwenden, aber ohne Erfolg. Was ich versuche zu tun:

var asyncTasks = []; 

app.post('/GetFooFromS1', function(req, res){ 

    asyncTasks.push(function(callback){ 
    // Send request to S1 
    S1.write({'type':'foo'}); 
    }); 

    async.parallel(asyncTasks, function(response){ 
    res.setHeader('Content-Type', 'application/json'); 
    res.json({'status':'success', 'value':response}); 
    }); 
}); 

und eine andere Aufgabe in S1DataParse:

function S1DataParse(){ 
    if(data.type='foo'){ 
    asyncTasks.push(function(callback){ 
     callback(data); 
    }); 
    } 
} 

Aber natürlich, die zweite Aufgabe nie zu dem asyncTasks Array hinzugefügt. Ich bin wirklich dabei geblieben. Können Sie mir bitte dabei helfen?

Dank

- = - = - = - Bearbeiten - = - = - = -

Schließlich kam ich mit Ereignissen accross und EventEmitter().

Von der POST-Anforderung ich die Funktion aufrufen, die Anforderungen an den Datenserver sendet (DataServerClientGet). In dieser Funktion registriere ich einen Listener, der die zukünftigen Daten erhält. eventEmitter.on ('getData', returnDataServerData);

Es funktioniert alles bis auf eine Sache. Immer wenn ich die Seite aktualisiere oder andere POST-Anforderungen hinzufüge, erhalte ich einen Fehler:

Fehler: Kann Kopfzeilen nicht einstellen, nachdem sie gesendet werden.

Es wäre großartig, wenn ich dieses Problem lösen würde. Hilf mir bitte.

Dank;)

Der gesamte Code sieht wie folgt aus:

var express = require('express'); 
var app = express(); 
var http = require('http').Server(app); 
var bodyParser = require('body-parser') 
var net = require('net'); 
var events = require('events'); 

var dataServerHost = '127.0.0.1'; 
var dataServerPort = 12345; 
var dataServerClient; 
var logMsg; 

var eventEmitter = new events.EventEmitter(); 


/*******************************************/ 
//    Init 
/*******************************************/ 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({extended: true})); 
app.use(express.static(__dirname + '/public')); 


/*******************************************/ 
//  Connect to the data server 
/*******************************************/ 
DataServerConnect(); 


/*******************************************/ 
// Open listener on port 3000 (to browser) 
/*******************************************/ 
http.listen(3000, function(){ 
    logMsg = 'listening on *:3000'; 
    console.log(logMsg); 
}); 


/*******************************************/ 
//    Routing 
/*******************************************/ 
app.get('/', function(req, res){ 
    res.sendFile(__dirname + '/index.html'); 
}); 

app.post('/GetDataFoo', function(req, res){ 
    var msg; 
    var size; 

    msg ='\n{"Type":"Query", "SubType":"GetDataFoo","SearchFilter":""}'; 
    size = msg.length; 

    logMsg = 'Client to DataServer: GetDataFoo'; 
    console.log(logMsg); 

    DataServerClientGet('GetDataFoo', size, msg, res); 
}); 


/*******************************************/ 
//    Functions 
/*******************************************/ 
function DataServerConnect(){ 
    dataServerClient = net.createConnection({'host':dataServerHost, 'port': dataServerPort}, function(){ 
    logMsg = 'Connected to DataServer ['+dataServerHost+':'+dataServerPort+']'; 
    console.log(logMsg); 
    }); 

    dataServerClient.on('data', function(data){ 

    logMsg = 'DataServerData>>>\n'+data.toString()+'DataServerData<<<'; 
    console.log(logMsg); 

    DataServerDataParse(data.toString()); 
    }); 

    dataServerClient.on('end', function(){ 
    logMsg = 'Disconnected from DataServer'; 
    console.log(logMsg); 
    }); 
} 

function DataServerClientGet(type, size, msg, res){ 
    dataServerClient.write('Type: Json\nSize: '+size+'\n\n'+msg, function(err){ 

    var returnDataServerData = function returnDataServerData(results){ 
    res.setHeader('Content-Type', 'application/json'); 
    res.json({'status':'success', 'value':results}); 
    } 
    eventEmitter.on('getData', returnDataServerData); 
} 

function DataServerDataParse(json){ 
    if(json.Type=='GetDataFoo') 
    { 
    var MessageList = json.MessageList; 
    eventEmitter.emit('getData', MessageList); 
    } 
} 

- = - = - = - Bearbeiten - = - = - = -

Die Fehler: Header können nach dem Senden nicht festgelegt werden. verursacht durch Hinzufügen des gleichen Listeners des gleichen Typs jedes Mal, wenn der DataServerClientGet aufgerufen wurde und die Res wurde mehrmals gesendet.

Ich löste dieses durch Hinzufügen: removeListener (Ereignis, Hörer) direkt nach dem res, in der Funktion. Wie auch immer, ich denke, es ist falsch und kann zu Problemen führen, wenn es mehr Gespräche nach DataServerClientGet mit dem gleichen Typ sein wird usw.

Antwort

0

Es gibt einen optionalen Rückruf Parameter, die Sie weitergeben können Funktion (docs) zu schreiben, so etwas wie:

S1.write({'type':'foo'},function(err){ 
    if(err){ 
    //Handle error 
    }else{ 
    res.setHeader('Content-Type', 'application/json'); 
    res.json({'status':'success', 'value':response}); 
    } 
}) 

Diese mit Post Weg arbeiten können, aber in Ihrem Zuhörer ‚Daten‘, man kann Daten vom Server zum Client senden, wenn eine Verbindung nicht dort von Client initialisiert ist (es ist nicht bidireccional), wenn Sie Sie bidireccional Verhalten wollen kann überprüfen socket.io

+0

Hallo, vielen Dank, der Rückruf im Schreiben war sehr hilfreich. Noch muss ich mich um die zurückkommenden Daten kümmern, die zu S1.on ('Daten') kommen. Wie bereits erwähnt, ist es async und ich muss das Ergebnis an die richtige POST-Anfrage anhängen. Auch muss ich irgendwo später auf den Code und nicht in die POST-Anfrage selbst einen Verweis auf res erhalten. –

+0

wie ich schon sagte, denke nicht, dass es möglich sein könnte, denn nach http Antwort gibt es keine Verbindung lebendig. – cshion

+0

Überprüfen Sie den zuletzt bearbeiteten Text und Code, den ich gepostet habe. Ich habe gemanaged, um die POST-Anfrage warten zu lassen, bis der Emitter die relevanten Daten vom anderen Server bekommt und erst dann die res zurückgibt. Die einzige Sache, die zu behandeln ist, ist der Fehler: Fehler: Kann Header nicht festlegen, nachdem sie gesendet werden. Ich habe auch das Gefühl, dass die Art, wie ich die Res durch den Code übergeben, nicht korrekt ist. Vielleicht bezieht sich der Fehler auf diese fehlerhafte Handhabung. –

Verwandte Themen