Я новичок в узле и застрял в обработке нескольких задач async.Узел js - как обрабатывать несколько асинхронных задач
За исключением узла, у меня есть еще один сервер (S1), который немедленно не возвращает данные на запросы, он может возвращать несколько типов данных, а также может отправлять уведомления, не запрашивая их конкретно, поэтому узел должен прослушивать данные из него, проанализировать его и действовать соответствующим образом.
Подключение к этому серверу (S1) осуществляется с помощью:
S1 = net.createConnection({'host':S1Host, 'port': S1Port});
И узел прослушивает данных с:
S1.on('data', function(data){
S1DataParse(data);
});
Я должен направлять правильные данные (после разбора его) к конкретному запросу POST.
Я попытался использовать для этого асинхронный модуль, но безуспешно. То, что я пытаюсь сделать:
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});
});
});
и еще одна задача в S1DataParse:
function S1DataParse(){
if(data.type='foo'){
asyncTasks.push(function(callback){
callback(data);
});
}
}
Но, конечно, вторая задача не добавляется в массив asyncTasks. Я действительно застрял в этом. Не могли бы вы мне помочь?
Благодаря
- = - = - = - Edit - = - = - = -
В конце концов, я наткнулся с событий и EventEmitter().
Из запроса POST я вызываю функцию, отправляющую запросы на сервер данных (DataServerClientGet). В этой функции я регистрирую слушателя, который получит будущие данные. eventEmitter.on ('getData', returnDataServerData);
Все работает отлично, за исключением одной вещи. Когда я обновляю страницу или добавляю другие запросы POST, я получаю сообщение об ошибке:
Ошибка: не удается установить заголовки после их отправки.
Было бы здорово решить эту проблему. Помоги мне, пожалуйста.
Спасибо;)
Весь код выглядит следующим образом:
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);
}
}
- = - = - = - Edit - = - = - = -
Ошибка: Невозможно установить заголовки после их отправки., вызванный добавлением одного и того же прослушивателя одного и того же типа каждый раз, когда вызывался DataServerClientGet, и res отправлял несколько раз.
Я решил это, добавив: removeListener (событие, слушатель) сразу после res, внутри функции. Во всяком случае, я думаю, что это неправильно и может вызвать проблемы, если будет несколько призванием DataServerClientGet с тем же типом и т.д.
Привет, Большое спасибо, обратный вызов в записи был очень полезным. Все еще я должен позаботиться о возвращенных данных, поступающих на S1.on ('data'). Как я уже говорил, это асинхронно, и я должен приложить результат к правильному запросу POST. Также мне нужно получить ссылку на res где-нибудь позже на код, а не на сам запрос POST. –
, как я уже сказал, не думаю, что это возможно, потому что после ответа HTTP return нет связи. – cshion
Проверьте последний отредактированный текст и код, которые я опубликовал. Мне удалось отправить запрос POST, пока эмиттер не получит соответствующие данные с другого сервера и только затем вернет res. Осталось только обработать ошибку: Ошибка: не удается установить заголовки после их отправки. У меня также появилось ощущение, что способ передачи пропусков через код неверен. Возможно, ошибка связана с этим неправильным обращением. –