2016-08-31 15 views
2

ノードの非同期性が私と協力し、コールバックやグーグルで何時間も後に問題を起こしています。私はついにあなたたちに目を向ける。'readline'を使用したnode.jsプログラムの同期実行

ノードのreadlineモジュールを使ってファイルから行を読み込む必要があるプログラムがあります。このファイルには、ノードプログラム内で定義された非同期関数に渡されるデータが含まれています。すべてのデータが正常に読み込まれて処理されると、このデータをJSON形式に解析して出力する必要があります。

ここで私の問題は、readLine.on('close', function() { ...... }を呼び出すと非同期関数の実行が終了する前に実行されるため、何も出力されずに残っていますが、プログラムは非同期関数を実行し続けます。

私はより明確に私の状況を説明しなければならない機能のシンプルなスケルトン作成しました:私は読書と解析を作ってみましたが、最初に/ secondAsynFunctionにコールバックを追加しようとしました

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! 

}); 

をプログラムの別々の関数のビットを作成し、コールバックを作成して、読み込みが完了したときにのみ構文解析を呼び出すようにしましたが、これらのソリューションのどれも動作していないようで、本当に苦労しています。

ありがとうございます!

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( "")を使用して2つの値を分割し、必要な関数に渡します。 IPDataは数値で、DataCentre値は文字列です。これが役に立ったらいいですか? – OliverOstach

答えて

1

非同期関数は値を返しませんが、代わりにコールバック関数を渡す必要があります。あなたの行

var processedData = 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') '、実行中** **非同期関数は終了し、結果を返しました..(これは私の問題でした、私は正しいことをすべて実行していることを確認できました!) – OliverOstach

+0

@OliverOstachあなたは単純に非同期関数の働きを理解できません。定義上、非同期関数**は値を返すことができないので、非同期呼び出しを停止します。値を返すと、 'onClose'イベントが発生する前に**実行しなければなりません。これは' v8'エンジンが動作するためです。私の答えがうまくいかないとどう思いますか?それを試しましたか?コピー&ペーストして正しく動作するようにします。 –

0

を記録します。

  1. あなたの人生をより楽にする約束を使用してください。
  2. インターフェイスに出力が定義されていないため、.closeを削除してください。

次のいずれかが発生したときに '近い' イベントが発せられる:

  1. rl.close()メソッドが呼び出され、readlineのれます。インタフェースインスタンスは入出力ストリームに対する制御を放棄しました。
  2. 入力ストリームは 'end'イベントを受け取ります。
  3. 入力ストリームは、信号終端送信(EOT)に-Dを受け取ります。
  4. 入力ストリームは-CをシグナルSIGINTに受け取り、readline.Interfaceインスタンスに登録されたSIGINTイベントリスナーは存在しません。
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

これはうまくいくようですが、データをどこに記録するか分かりませんが、すべてのasynchnorous関数がログの段階で実行されているはずです – OliverOstach

関連する問題