Как использовать преобразование узлов для преобразования одного объекта в другой

Я новичок в потоках Node и пытаюсь понять, почему что-то работает не так, как ожидалось. Я просто тренируюсь и хочу сделать глупое преобразование.

interface MyTransformStreamOptions {
  [key: string]: any
}

class MyTransformStream extends Transform {
  constructor(options) {
    options.readableObjectMode = true;
    options.writableObjectMode = true;

    super(options);
  }

  _transform(chunk, encoding, callback) {
    console.info('encoding: ' + encoding);

    // chunk should be an object here, due to
    // readableObjectMode = true right?

    const newObj = {};

    for (const [key, value] of Object.entries(chunk)) {
      console.info(`[key, value]: [${key}, ${value}]`);
      newObj['aa' + key] = 'bb' + value;
    }

    callback(null, newObj);
  }
}

const myTransformStream = new MyTransformStream({} as MyTransformStreamOptions);

process.stdin
  .pipe(myTransformStream)
  .pipe(process.stdout);

Наконец, я запускаю скрипт и ввожу его через стандартный ввод:

{ car: 'honda', truck: 'mazda' }

а также я пробовал:

"{ car: 'honda', truck: 'mazda' }"

Но цикл обрабатывает фрагмент как строку, а не как объект. Итак, я вижу такой результат:

[key, value]: [0, 123]
[key, value]: [1, 32]
...etc...

Я пробовал разные комбинации:

options.readableObjectMode = true/false;
options.writableObjectMode = true/false;

А также в _transform() с использованием:

const obj = JSON.parse(chunk.toString());

но obj никогда не является объектом и всегда является строкой.

Моя цель - получить объект в поток преобразования, изменить его и вывести. Но я застреваю, имея дело только со строками, которые я не могу преобразовать в объекты даже с JSON.parse().

Где я здесь ошибаюсь?

Обновление - частичное решение

Проблема была в том, что я использовал JSON.parse(). Я пытался разобрать:

{ car: 'honda', truck: 'mazda' }

Это действительный JS, но недействительный JSON, да!

Однако остается более серьезная проблема. Я установил для потока преобразования значение: writableObjectMode = true, но когда я это сделаю:

callback(null, newObj);

Я получаю сообщение об ошибке:

TypeError: Invalid data, chunk must be a string or buffer, not object

Если я сделаю:

callback(null, JSON.stringify(newObj));

все работает как положено.

Однако разве это не должно работать без строкового преобразования, учитывая, что я настроил все в объектном режиме?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
1 194
2

Ответы 2

Объектный режим не преобразует поток из буфера (это буфер, а не строка) в объект, он просто позволяет типу данных быть типами, отличными от буфера или строки. Вам необходимо использовать поток преобразования для преобразования буфера стандартного ввода в объект, например:

const ndjson = require('ndjson');

. . .

process.stdin
  .pipe(ndjson.parse())
  .pipe(myTransformStream)
  .pipe(process.stdout);

Спасибо за совет, но использование ndjson просто не меняет того поведения, которое я наблюдаю. Кроме того, что касается потока, являющегося буфером, строки vs и т. д., Из документации Node: chunk <Buffer> | <строка> | <any> Фрагмент, который нужно преобразовать. Всегда будет буфером, если для параметра decodeStrings не задано значение false или поток не работает в объектном режиме. И в другом месте на той же странице документа: все потоки, созданные API-интерфейсами Node.js, работают исключительно со строками и объектами Buffer (или Uint8Array). Однако реализации потоков могут работать с другими типами значений JavaScript.

lostdorje 09.04.2018 07:39

Итак, основные проблемы с моим кодом - это использование stdin и stdout. Это потоки, которые работают в строковом / буферном режиме. Используя их как есть, конвейерный ввод stdin в поток будет передаваться в строковом / буферном режиме, а не в объектном режиме. То же самое и с stdout.

Я проверил свою гипотезу, создав читаемый поток в объектном режиме, который имитировал мой ввод stdin, который я вводил с помощью метода _read(), а затем заставил мой поток преобразования преобразовать кусок как объект, который читаемый поток передал в него.

Труба к стандартному выходу все еще терпела неудачу, поскольку принимала объекты из коробки. Я подтвердил это, создав другой поток преобразования, который просто преобразовал объект в строку через JSON.stringify(), и затем stdout снова был счастлив.

Все проблемы, которые у меня были с «режимами чтения / записи объекта», были просто потому, что у меня были stdin и stdout по обе стороны от моего потока преобразования.

Другие вопросы по теме