Почему отправка объекта Date в виде сообщения из рабочего потока преобразует его в строку? - PullRequest
1 голос
/ 05 марта 2019

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

Чего я не понимаю, так это того, что всякий раз, когда я отправляю сообщение, содержащее объект Date, этот объект Date преобразуется в строку. Кажется смешным разбирать их по датам как в рабочих потоках, так и в основном. Я работаю с большим количеством дат, так что это будет иметь огромный успех.

Что я могу сделать, чтобы обойти это? Я использую версию узла v10.13.0.

const cluster = require('cluster');

if (cluster.isMaster) {
  // init cluster
  require('os').cpus().forEach(() => {
    cluster.fork();
  });

  // add eventlisteners
  Object.values(cluster.workers).forEach(worker => {
    worker.on('message', message => {
      console.log(typeof message); // string
    });
  });
} else {
  process.send(new Date());
}

1 Ответ

1 голос
/ 05 марта 2019

Согласно 'message' документации о событии :

Сообщение проходит сериализацию и анализ.

Сериализация объекта Date представляет собой строку:

// serialize and rebuilds an object: { test: "2019-03-05T16:20:17.863Z" }
JSON.parse(JSON.stringify({test: new Date()}));

Итак, нет, обходного пути нет: каждый процесс (как рабочий, так и главный) имеет свою собственную среду (т. Е. Свое собственное пространство для хранения объектов), поэтому вы не можете делиться ссылками в разных средах. Для иллюстрации:

const input = {some: 'thing'};
const output = JSON.parse(JSON.stringify(input));
console.log('are input and output the same object?', input === output); // false

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

В качестве примечания вы можете повысить производительность, используя внутреннюю временную метку Date вместо строки времени по умолчанию:

const t0 = new Date();
for (let i = 0; i < 1000000; i++) {
    const tmp = new Date();
    // this took ~6.9s on JSFiddle
    new Date(JSON.parse(JSON.stringify(tmp)));
    // this took ~2.8s on JSFiddle
    new Date(JSON.parse(JSON.stringify(+tmp)));
}
const t1 = new Date();
console.log('time spent', t1 - t0);
...