世界杯夺冠国家

Web Worker API

传递数据的例子

例子 1:传输 JSON 的高级方式和创建一个交换系统

如果你需要传输非常复杂的数据,还要同时在主页与 Worker 内调用多个方法,那么可以考虑创建一个类似下面的系统。

首先,我们创建一个 QueryableWorker 的类,它接收 worker 的 URL、一个默认侦听函数和一个错误处理函数作为参数,这个类将会记录所有的侦听的列表并且帮助我们与 worker 进行通信。

jsfunction QueryableWorker(url, defaultListener, onError) {

const instance = this;

const worker = new Worker(url);

const listeners = {};

this.defaultListener = defaultListener ?? (() => {});

if (onError) {

worker.onerror = onError;

}

this.postMessage = (message) => {

worker.postMessage(message);

};

this.terminate = () => {

worker.terminate();

};

}

紧接着,我们写出新增和删除侦听的方法。

jsthis.addListeners = (name, listener) => {

listeners[name] = listener;

};

this.removeListeners = (name) => {

delete listeners[name];

};

这里我们让 worker 处理 2 个这样的简单操作:区别 2 个数字并在 3 秒后弹框提示。为了完成这个操作,我们首先实现一个 sendQuery 方法,该方法可以查询 worker 是否真正有我们所需要的对应方法。

js// 该函数至少需要一个参数,即我们想要查询的方法名称。

// 然后我们可以传入方法所需的参数。

this.sendQuery = (queryMethod, ...queryMethodArguments) => {

if (!queryMethod) {

throw new TypeError(

"QueryableWorker.sendQuery takes at least one argument",

);

}

worker.postMessage({

queryMethod,

queryMethodArguments,

});

};

我们以 onmessage 方法作为 QueryableWorker 的结尾。如果 worker 有我们所需要的对应的方法,它就会返回相对应的侦听方法的名字以及所需要的参数,我们只需要在侦听列表 listeners 中找到它:

jsworker.onmessage = (event) => {

if (

event.data instanceof Object &&

Object.hasOwn(event.data, "queryMethodListener") &&

Object.hasOwn(event.data, "queryMethodArguments")

) {

listeners[event.data.queryMethodListener].apply(

instance,

event.data.queryMethodArguments,

);

} else {

this.defaultListener.call(instance, event.data);

}

};

现在回到 worker 中。首先我们需要一个能够完成这 2 个操作的方法:

jsconst queryableFunctions = {

getDifference(a, b) {

reply("printStuff", a - b);

},

waitSomeTime() {

setTimeout(() => {

reply("doAlert", 3, "seconds");

}, 3000);

},

};

function reply(queryMethodListener, ...queryMethodArguments) {

if (!queryMethodListener) {

throw new TypeError("reply - takes at least one argument");

}

postMessage({

queryMethodListener,

queryMethodArguments,

});

}

// 当主页面直接调用 QueryWorker 的 postMessage 方法时,该方法被调用。

function defaultReply(message) {

// 做点什么

}

onmessage 方法也就很简单了:

jsonmessage = (event) => {

if (

event.data instanceof Object &&

Object.hasOwn(event.data, "queryMethod") &&

Object.hasOwn(event.data, "queryMethodArguments")

) {

queryableFunctions[event.data.queryMethod].apply(

self,

event.data.queryMethodArguments,

);

} else {

defaultReply(event.data);

}

};

接下来给出一个完整的实现:

example.html(主页面):

html

MDN Example - Queryable worker

my_task.js(worker 文件):

jsconst queryableFunctions = {

// 示例 1:得到两个数字的差值:

getDifference(minuend, subtrahend) {

reply("printStuff", minuend - subtrahend);

},

// 示例 2:等待三秒

waitSomeTime() {

setTimeout(() => {

reply("doAlert", 3, "seconds");

}, 3000);

},

};

// 系统函数

function defaultReply(message) {

// 你的默认 PUBLIC 函数只在主页面直接调用 queryableWorker.postMessage() 方法时执行。

// 做点什么

}

function reply(queryMethodListener, ...queryMethodArguments) {

if (!queryMethodListener) {

throw new TypeError("reply - not enough arguments");

}

postMessage({

queryMethodListener,

queryMethodArguments,

});

}

onmessage = (event) => {

if (

event.data instanceof Object &&

Object.hasOwn(event.data, "queryMethod") &&

Object.hasOwn(event.data, "queryMethodArguments")

) {

queryableFunctions[event.data.queryMethod].apply(

self,

event.data.queryMethodArguments,

);

} else {

defaultReply(event.data);

}

};

这个实例中,可以对从主页面到 worker、以及 worker 到主页面之间传递的消息内容进行切换。而且属性名 "queryMethod"、"queryMethodListeners" 和 "queryMethodArguments" 可以是任何东西,只要它们在 QueryableWorker 和 worker 中保持一致。

Copyright © 2088 中国举办世界杯_世界杯足球场地尺寸 - lchjdj.com All Rights Reserved.
友情链接