2016-08-31 14 views
2

У меня возникли проблемы с получением асинхронного характера узла для взаимодействия со мной, а также после часов обратных вызовов и поиска в Google; Наконец я обращусь к вам, ребята.Синхронное выполнение для программы node.js с использованием 'readline'

У меня есть программа, которая должна читаться в строках из файла с помощью модуля readline узла. Этот файл содержит данные, которые передаются некоторым асинхронным функциям, определенным в моей программе узлов. После того как все данные будут успешно прочитаны и обработаны, эти данные должны быть проанализированы в формате JSON, а затем выведены.

Моя проблема заключается в том, что когда я звоню: readLine.on('close', function() { ...... }, это выполняется до того, как асинхронные функции закончатся, и поэтому я остаюсь без вывода ничего, но программа продолжает работать асинхронные функции.

Я создал простой скелет функций, которые должны объяснить мою ситуацию более ясно:

function firstAsyncFunc(dataFromFile) { 
    //do something asynchronously 

    return processedData; 
} 


function secondAsyncFunc(dataFromFile) { 
    //do something else asynchronously 

    return processedData; 
} 


//create readline 
var lineReader = require('readline').createInterface({ 
    input: require('fs').createReadStream('data.txt') 
}); 


//array to hold all the data processed 
var totalDataStorage; 


//read file 
lineReader.on('line', function(line) { 

    var processedData = firstAsyncFunction(line); 
    var moreProcessedData = secondAsyncFunction(line); 


    //store processed data and concatenate into one array 
    var tempDataStorage = [{ 'first': processedData, 'second': moreProcessedData }] 
    totalDataStorage = totalDataStorage.concat(tempDataStorage); 

}).on('close', function() { 

    var JSONString = JSON.stringify(... //create JSON for totalDataStorage ...); 
    console.log(JSONString); //DOESN'T OUTPUT ANYTHING! 

}); 

Я пытался добавить функцию обратного вызова к первому/secondAsynFunction, я попытался сделать чтение и синтаксический бит программных отдельных функций и создавать обратные вызовы, так что синтаксический анализ вызывается только при чтении, но ни одно из этих решений, похоже, не работает, и я действительно борюсь - так что любая помощь будет оценена.

Спасибо!

EDIT: data.txt файл формы

IPData1 DataCenter1 
IPData2 DataCenter2 
... 
IPDataN DataCenterN 

Я использую str.split (»«), чтобы получить соответствующие значения, а затем передать их соответствующим образом. IPData - это число, а DataCenter - строка

+0

вы можете поделиться файл data.txt? я верю, что смогу ответить на ваш вопрос – Bamieh

+0

@JaromandaX Смотрите еще раз код OP. Это массив, а не строка. –

+0

Файл data.txt имеет следующий вид: 'IPData, DataCentre'. В реальной программе я использую str.split (""), чтобы разделить два значения, а затем передать их в нужную функцию. IPData - это число, а значение DataCentre - строка. Надеюсь, это поможет – OliverOstach

ответ

1

Асинхронные функции не возвращают значение, но вместо этого вы должны передать ему функцию обратного вызова. Ваша линия

var обработанныйData = firstAsyncFunction (линия);

не имеет смысла вообще. Если ваш файл data.txt выглядит следующим образом

IPData1 DataCenter1 
IPData2 DataCenter2 
IPData3 DataCenter3 

вы можете прочитать данные следующим образом

var fs = require('fs'); 
var rl = require('readline').createInterface({ 
    input: fs.createReadStream('data.txt') 
}); 
var arr = []; 

rl.on('line', a => { 
    a = a.split(' '); 
    arr.push({ 
    first: a[0], 
    second: a[1] 
    }); 
}).on('close',() => { 
    console.log(JSON.stringify(arr, null, 2)); 
}); 

Он будет регистрировать

[ 
    { 
    "first": "IPData1", 
    "second": "DataCenter1" 
    }, 
    { 
    "first": "IPData2", 
    "second": "DataCenter2" 
    }, 
    { 
    "first": "IPData3", 
    "second": "DataCenter3" 
    } 
] 
+0

Благодарим за помощь, но, к сожалению, это не сработает. Я зарегистрировал функцию обратного вызова для возврата результатов из асинхронных функций, а затем вызвал их соответствующим образом из 'lineReader.on ('line', ...)', но у меня все еще есть такая же проблема ' .on ('close') ', запуск ** ПЕРЕД ** функции async завершили и вернули результат .. (это была моя проблема, я смог проверить, что я делаю все остальное правильно!) – OliverOstach

+0

@OliverOstach Вы просто не можете понять, как работают асинхронные функции. По определению асинхронная функция ** CAN NOT ** возвращает значение, поэтому перестаньте его асинхронно. Если он возвращает значение, тогда он ** ДОЛЖЕН запускать ** перед запуском события 'onClose', потому что он работает так, как работает движок' v8'. Как вы думаете, мой ответ не работает? Вы попробовали? Скопируйте его, чтобы убедиться, что он работает правильно. –

0

я изменил следующее и его работать на местном уровне.

  1. Использование обещает сделать вашу жизнь проще.
  2. удалить .close, так как у вас нет выхода, определенного в интерфейсе.

'закрыть' событие генерируется, когда один из следующих случаев:

  1. Метод rl.close() вызывается и Readline.Экземпляр интерфейса отказался от управления входными и выходными потоками;
  2. Входной поток принимает свое событие «конец»;
  3. Входной поток принимает -D для передачи сигнала конца передачи (EOT);
  4. Входной поток принимает сигнал -C для сигнала SIGINT и нет прослушивателя событий SIGINT, зарегистрированного на экземпляре readline.Interface.
function firstAsyncFunc(dataFromFile) { 
    return new Promise(function(resolve, reject) { 
    //do something asynchronously 
    resolve(result); 
    }) 
} 

function secondAsyncFunc(dataFromFile) { 
    return new Promise(function(resolve, reject) { 
    //do something asynchronously 
    resolve(result); 
    }) 
} 

//create readline 
var lineReader = require('readline').createInterface({ 
    input: require('fs').createReadStream('data.txt') 
}); 

//array to hold all the data processed 
var totalDataStorage; 

//read file 
lineReader.on('line', function(line) { 
    Promise.all([ 
     firstAsyncFunc(line), 
     secondAsyncFunc(line) 
    ]) 
    .then(function(results) { 
     var tempDataStorage = [{ 
     'first': results[0], 
     'second': results[1] 
     }]; 
     // i'd use push instead of concat 
     totalDataStorage = totalDataStorage.concat(tempDataStorage); 
    }); 
}) 
+0

Кажется, что это может сработать, но я просто не могу понять, где я буду записывать данные таким образом, чтобы все асинхронные функции выполнялись на этапе каротажа – OliverOstach

Смежные вопросы