Javascript WebWorker - Async/Await

会有一股神秘感。 提交于 2021-01-20 20:46:06

问题


I am trying to offload long running process that blocks my UI.

The WebWorker approach appears to be the best approach to this situation.

However, one of the libraries that I need to use has async/await.

The WebWorker has a limited JS API and does not appear to have async/await.

Is there a way to use Promises inside of a WebWorker?

Error

ReferenceError: __awaiter is not defined

Regards,

Daniel

Update:

Adding an __awaiter lead to the Promise not being recognised.

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);
            });
        }

Here is the skeleton code for how the web worker is constructed.

/* 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:


async/await are part of ECMAScript language, and these are available in all global scopes, be it Window, Web Worker, Service Worker, Audio Worklet, Paint Worklet etc.

What these scopes may not have are some Web APIs, like the DOM API, MediaDevices API, Geolocation API and a few others. However, as long as the browser supports this ECMAScript feature, then all scopes will.

So I can't tell what is your problem, but it is definitely possible to use Promises and async/await in a 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>


来源:https://stackoverflow.com/questions/55999143/javascript-webworker-async-await

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!