1

fast-csv 内でファイバーを使用して、その行がさまざまな非同期呼び出しを完了するまで各行で読み取り/処理を一時停止する行ごとのリーダー (単一ユーザー コマンド ライン スクリプト) を作成する方法を理解しようとしています。 . (自分のcsvコードを転がさずに、csvフォーマットに関して問題をすでに把握しているものを使用したい)

私がこれをしたら

var csv = require("fast-csv");

var CSV_STRING = 'a,b\n' +
'a1,b1\n' +
'a2,b2\n';

csv
.fromString(CSV_STRING, {headers: false})
.on("record", function (data) {
    console.log("line="+JSON.stringify(data));
    setTimeout(function(){
        console.log("timeout");
    },2000);
})
.on("end", function () {
    console.log("done parsing CSV records");
});
console.log("done initializing csv parse");

私が期待するものを手に入れます:

done initializing csv parse
line=["a","b"]
line=["a1","b1"]
line=["a2","b2"]
done parsing CSV records
timeout
timeout
timeout

各レコードの後に​​ファイバーを使用して生成しようとすると

Fiber(
    function () {
        var fiber = Fiber.current;

        csv
            .fromString(CSV_STRING, {headers: false})
            .on("record", function (data) {
                console.log("line="+JSON.stringify(data));
                setTimeout(function(){
                    console.log("timeout");
                    fiber.run();
                },2000);
                Fiber.yield();
            })
            .on("end", function () {
                console.log("done parsing CSV records");
            });
        console.log("done initializing csv parse");
    }).run();

私は得る

done initializing csv parse
line=["a","b"]
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: yield() called with no fiber running

何が起こっているのか理解していると思います.Fiber().run()のコードが終了するため、収量が呼び出される前にファイバーを離れるため、収量に達するとファイバーがなくなります。(したがって、巧妙なエラーメッセージ「ファイバーが実行されていません」)

解析が完了するまでファイバーを実行し続けるための適切な方法は何ですか?

とても単純な質問のように思えますが、明らかな答えが見えませんか? 最初は、Future().run() を出る直前に利回りを置くことを考えましたが、最初の fiber.run() が再びファイバーを離れさせるため、うまくいきません。

私が望んでいるのは、フローが次のようになることです。

done initializing csv parse
line=["a","b"]
timeout
line=["a1","b1"]
timeout
line=["a2","b2"]
timeout
done parsing CSV records

しかし、fast-csv はレコードごとにいつイベントが発生するかを制御するため、fast-csv の内部を作り直さないと不可能かもしれません。私の現在の考え方は、各イベントが fast-csv 内で発生するたびに降伏し、ユーザーが csv.on("record") でイベントを処理して、csv を高速で解析するループに制御を戻す必要があるというものです。 -csv.

4

2 に答える 2

0

ストリームは一時停止/再開可能です:

var csv = require("fast-csv");

var CSV_STRING = 'a,b\n' +
    'a1,b1\n' +
    'a2,b2\n';

var stream = csv.fromString(CSV_STRING, { headers: false })
    .on("data", function (data) {
        // pause the stream
        stream.pause();
        console.log("line: " + JSON.stringify(data));
        setTimeout(function () {
            // all async stuff are done, resume the stream
            stream.resume();
            console.log("timeout");
        }, 2000);
    }).on("end", function () {
        console.log("done parsing CSV records");
    });

コンソール出力は、ほぼ正確にあなたが望むものです:

/*
line: ["a","b"]
timeout
line: ["a1","b1"]
timeout
line: ["a2","b2"]
done parsing CSV records
timeout
*/

csv を同期的に読み取る必要がある理由をお聞きしてもよろしいですか?

于 2016-01-29T08:51:18.300 に答える