Javascript WebWorker - Async / Await - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь разгрузить длительно работающий процесс, который блокирует мой пользовательский интерфейс.

Подход WebWorker представляется наилучшим подходом в этой ситуации.

Однако одна из библиотек, которая мне нужнаиспользовать async / await.

WebWorker имеет ограниченный JS API и, по-видимому, не имеет async / await.

Есть ли способ использовать Promises внутри WebWorker?

Ошибка

ReferenceError: __awaiter не определен

С уважением,

Даниэль

Обновление:

Добавление __awaiter ведет к тому, что Обещание не распознается.

var __awaiter =
        (this && this.__awaiter) ||
        function(thisArg, _arguments, Promise, generator) {
            return new Promise(function(resolve, reject) {
                generator = generator.call(thisArg, _arguments);
                function cast(value) {
                    return value instanceof Promise && value.constructor === Promise
                        ? value
                        : new Promise(function(resolve) {
                                resolve(value);
                          });
                }
                function onfulfill(value) {
                    try {
                        step('next', value);
                    } catch (e) {
                        reject(e);
                    }
                }
                function onreject(value) {
                    try {
                        step('throw', value);
                    } catch (e) {
                        reject(e);
                    }
                }
                function step(verb, value) {
                    var result = generator[verb](value);
                    result.done
                        ? resolve(result.value)
                        : cast(result.value).then(onfulfill, onreject);
                }
                step('next', void 0);
            });
        }

Ниже приведен скелетный код для построения веб-работника.

/* eslint-disable */
export default function ModelWorker() {
  this.window = this

  onmessage = async (e) => {
    console.log(e);
  }
}

WorkerProxy.js

export default class WorkerProxy {
  constructor(worker) {
    const code = worker.toString()
    const src = code.substring(code.indexOf('{') + 1, code.lastIndexOf('}'))
    const blob = new Blob([src], { type: 'application/javascript' })
    return new Worker(URL.createObjectURL(blob))
  }
}

SomeComponent.js

import WorkerProxy from './WorkerProxy'
import ModelWorker from './ModelWorker'


if (!!window.Worker) {
  const worker = new WorkerProxy(ModelWorker)
  worker.addEventListener('message', e => console.log(e.data))
  worker.postMessage({ message:message })
  // Load labels, etc.
}

1 Ответ

1 голос
/ 06 мая 2019

async / await являются частью языка ECMAScript , и они доступны во всех глобальных областях, будь то Window, Web Worker, Service Service, Audio Worklet, Paint Worklet и т. Д.

То, что эти области могут не иметь, это некоторые веб-API, такие как DOM API, MediaDevices API, Geolocation API и некоторые другие.Однако, пока браузер поддерживает эту функцию ECMAScript, тогда все области будут.

Так что я не могу сказать, в чем ваша проблема, но определенно возможно использовать Promises и async / await в Worker.

const worker = new Worker(
  URL.createObjectURL(
    new Blob([worker_script.textContent])
  )
);
worker.onmessage = ({data}) => console.log(data);
<script type="worker-script" id="worker_script">
  (async function() {
    postMessage(['starting', performance.now()]);
    await wait(2000);
    postMessage(['ended', performance.now()]);
  })();
  function wait(time) {
    return new Promise((res)=>setTimeout(res, time));
  }
</script>
...