Разные строки с заголовком и обещанием - PullRequest
2 голосов
/ 26 февраля 2020

Я использую в своем проекте функцию:

function readStream(file) {

    console.log("starte lesen");

    const readStream = fs.createReadStream(file);
    readStream.setEncoding('utf8');

    return new Promise((resolve, reject) => {
        let data = "";

        readStream.on("data", chunk => data += chunk);
        readStream.on("end", () => {resolve(data);});
        readStream.on("error", error => reject(error));
    });
}

Он будет читать файл xml с длиной строки около 800. Если я добавлю:

readStream.on("end", () => {console.log(data); resolve(data);});

, тогда xml данные завершены. Все хорошо. Но если я сейчас вызываю readStream из другой функции:

const dpath = path.resolve(__basedir, 'tests/downloads', 'test.xml');
let xml = await readStream(dpath);
console.log(xml);

, тогда данные XML обрезаются. Я думаю, что 800 строк ничего особенного. Так что может случиться, что данные обрезаются в этой позиции, но не в самой функции.

Ответы [ 3 ]

0 голосов
/ 26 февраля 2020

Иногда син c + асин c код может получить состояние гонки, когда он вызывается в том же тике. Попробуйте использовать setImmediate(resolve, data) в вашем обработчике событий, который разрешится на следующем тике процесса.

В качестве альтернативы, если вы нацеливаетесь на узел v12 или выше, вы можете использовать stream asyn c iterator интерфейс, который будет намного чище для вашего кода:

async function readStream(file) {

    console.log("starte lesen");

    const readStream = fs.createReadStream(file);
    readStream.setEncoding('utf8');

    let data = "";
    for await (const chunk of readStream) {
        out += chunk;
    }
    return out;
}
0 голосов
/ 27 февраля 2020

Если вы используете современную версию узла, есть fs.promises

const { promises: fs } = require('fs')

;(async function main() {
    console.log(await fs.readFile('./input.txt', 'utf-8'));
})()
0 голосов
/ 26 февраля 2020

Я пробовал это следующим образом, мне кажется, что он работает.

Для полного выполнения примера клона node-cheat xml -streamer и выполните node main.js.

xml -стример. js:

const fs = require('fs');

module.exports.readStream = function (file) {
    console.log("read stream started");
    const readStream = fs.createReadStream(file);
    readStream.setEncoding('utf8');
    return new Promise((resolve, reject) => {
        let data = "";
        readStream.on("data", chunk => data += chunk);
        readStream.on("end", () => {console.log(data); resolve(data);});
        readStream.on("error", error => reject(error));
    });
}

основной. js:

const path = require('path');
const _streamer = require('./xml-streamer');

async function main() {
    const xml = await _streamer.readStream( path.resolve(__dirname, 'files', 'test.xml'));
    console.log(xml);
}

main();

PS В вышеупомянутом тесте узла-чит xml файл имеет 1121 строк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...