Javascript WebWorker-异步/等待 [英] Javascript WebWorker - Async/Await
问题描述
我正在尝试卸载长时间运行的进程,该进程会阻塞我的UI.
I am trying to offload long running process that blocks my UI.
WebWorker方法似乎是解决这种情况的最佳方法.
The WebWorker approach appears to be the best approach to this situation.
但是,我需要使用的一个库具有async/await.
However, one of the libraries that I need to use has async/await.
WebWorker具有受限的JS API,并且似乎没有异步/等待状态.
The WebWorker has a limited JS API and does not appear to have async/await.
是否可以在WebWorker中使用Promises?
Is there a way to use Promises inside of a WebWorker?
错误
ReferenceError:未定义__awaiter
ReferenceError: __awaiter is not defined
此致
丹尼尔
更新:
添加__awaiter导致Promise未被识别.
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);
});
}
这是构建Web Worker的基本代码.
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
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
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
是 ECMAScript语言的一部分,它们是在所有全局范围内可用,包括Window,Web Worker,Service Worker,Audio Worklet,Paint Worklet等.
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.
这些作用域可能没有的是一些Web API,例如DOM API,MediaDevices API,Geolocation API等.但是,只要浏览器支持此ECMAScript功能,所有作用域都将起作用.
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.
所以我不能说出您的问题是什么,但是绝对可以在Worker中使用Promises和async/await.
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>
这篇关于Javascript WebWorker-异步/等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!