Вызов Papa.parse в worker с _config.worker = false вызывает postMessage

Я звоню Papa.parse в моем собственном рабочем и в _config.workerустановлено false. Когда процесс завершается, он вызываетpostMessageтем не менее, это вызывает сообщение для моего рабочего. Разве это не должно

if (IS_PAPA_WORKER)
{
    global.postMessage({
        results: results,
        workerId: Papa.WORKER_ID,
        finished: finishedIncludingPreview
    });
}

Следует также проверить, если config.worker установлен на true тогда только позвони global.postMessage Я не хочу отправлять результаты в основной поток. Не знаю, как мне этого добиться?

2 ответа

Решение

Они определяютIS_PAPA_WORKER к

var IS_WORKER = !global.document && !!global.postMessage,
    IS_PAPA_WORKER = IS_WORKER && /blob:/i.test((global.location || {}).protocol);

Это означает, что они проверяют, нет ли document собственность, а postMessage свойство, и если текущая область была загружена из blob: URI.

Лучшее решение в вашем случае - это, вероятно, не загружать ваш скрипт из blob: URI, но вместо этого используйте специальный файл сценария.

const worker = new Worker( '/a_real_file.js' );

Вот демонстрация с использованием data: URI, поскольку StackSnippets не разрешает хранение файлов, но не использует data: Сами URI, протокол имеет значение только для демонстрации:

const worker_script = document.querySelector( '[type="worker-script"]' ).textContent;
const worker_url = 'data:text/javascript,' + encodeURIComponent( worker_script );
const worker = new Worker( worker_url );
worker.onmessage = ({data}) => console.log( data );
worker.onerror = console.error;
<script type="worker-script">
  importScripts( 'https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js' );
  
  const csv = `col1,col2,col3
a,1,z
b,2,y
c,3,x`;
  Papa.parse( csv, { header: true } );
  postMessage( 'worker done' );
</script>

Теперь, если вам абсолютно необходимо использовать blob: URI, самое простое решение - определить document как истинное глобальное свойство перед импортом библиотеки:

const worker_script = document.querySelector('[type="worker-script"]').textContent;
const worker_url = URL.createObjectURL( new Blob( [ worker_script ], { type: 'text/javascript' } ) );
const worker = new Worker( worker_url );
worker.onmessage = ({data}) => console.log( data );
<script type="worker-script">
  self.document = {};
  importScripts( 'https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js' );
  
  const csv = `col1,col2,col3
a,1,z
b,2,y
c,3,x`;
  Papa.parse( csv, { header: true } );
  postMessage( 'worker done' );
</script>

Кто использует worker-loader в webapck не используйте встроенный импорт

this.worker = await import(/* webpackChunkName: "MyWorker" */ 'workers/MyWorker') это импортирует его как BLOB

импортировать его с помощью import MyWorker from 'worker-loader!./MyWorker.js'; это импортирует его как файл и не вызовет проблем.

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