简体   繁体   中英

Javascript WebWorker - Async/Await

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.
}

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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM