此类用于执行位于模块上的远程方法,这些模块通过 workers framework 加载到单独的线程中。
workers.open() 方法可加载脚本并向主线程返回 Promise。解析后,您可以访问 Connection 的实例,该实例允许您通过 invoke() 或 broadcast() 方法调用模块的方法。
调用远程方法
若要将工作委托给 worker,则需要创建一个公开函数的模块或将由框架进行实例化的类。每个远程方法只能接受一个参数。参数值可以是任何基元类型,也可以是由结构化克隆算法处理的 JavaScript 对象,或是使用其中一个基元类型解析的 JavaScript Promise。
例如,让我们创建一个简单的 worker 来计算数字数组的总和。
// Module loaded in worker : calculator.js
export function getSum(numbers) {
let sum = 0;
for (let i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
return sum;
}
现在,我们将计算器模块加载到一个 worker 中并调用其 getSum
函数。
// Module loaded in main thread
export function getSumAsync(numbers) {
let connection = null;
return workers.open("./calculator.js")
.then(function(conn) {
// Keep the connection reference to later close it.
connection = conn;
return connection.invoke("getSum", numbers);
})
.then(function(result) {
// close the connection
connection.close();
connection = null;
return result;
});
}
// Invoke our method.
getSumAsync([0, 2, 4, 6, 8])
.then(function(result) {
console.log("Result:", result);
});
传递多个参数
如上所述,使用 worker 加载的远程方法只能接受一个参数。但是,要将多个参数传递给远程方法,请使用具有多个密钥值对的 JavaScript 对象。
下面的示例显示了一个函数,该函数将数字数组乘以一个因子。
// Module loaded in worker : calculator.js
export function mapMultiply(params) {
// params has numbers and factor values.
let numbers = params.numbers;
let factor = params.factor;
for (let i = 0; i < numbers.length; i++) {
numbers[i] *= factor;
}
return numbers;
}
若要调用此函数,需要将具有两个属性的对象传递到函数中。
// Module loaded in main thread
export function mapMultiplyAsync(numbers, factor) {
let connection = null;
return workers.open("./calculator.js")
.then(function(conn) {
// Keep the connection reference to later close it.
connection = conn;
// invoke mapMultiply and pass in object with two key-value pairs.
return connection.invoke("mapMultiply", {
numbers: numbers,
factor: factor
});
})
.then(function(result) {
// close the connection after we are done.
connection.close();
connection = null;
return result;
});
}
// Invoke the method.
mapMultiplyAsync([0, 2, 4, 6, 8], 2)
.then(function(result) {
console.log("Result:", result);
});
使用 transferables
Transferable
对象可用于在主线程和 worker 线程之间传输数据,以避免复制数据。使用此方法,对象的所有权将转移到其他上下文。使用此技术可使用 ArrayBuffers、MessagePort 或 ImageBitmap 传输大量内存。
注
Transferable
接口从技术上讲不再存在。Transferable
对象的功能仍然存在,但是在更基础的级别实现 (从技术上讲,使用 [Transferable]
WebIDL 扩展属性)。另请参阅 Transferable 对象。
要将对象传输给 worker,请使用 invoke()
方法的 transferList
参数。对于使用 transferable 对象返回或解析的远程方法,返回的结果必须具有两个属性:result
和 transferList
。result
是一个对象,而 transferList
是 transferable 对象数组。请注意,transferList
中的每个 transferable 对象都应在 result
的对象结构中。
让我们重温前面的示例以探索 transferable 对象。
// Module loaded in worker : calculator.js
export function mapMultiplyFloat64(params) {
// the numbers parameter is an ArrayBuffer
// we create a typed array from it.
let numbers = new Float64Array(params.numbers);
let factor = params.factor;
for (let i = 0; i < numbers.length; i++) {
numbers[i] *= factor;
}
// Transfer back the buffer
return {
result: numbers.buffer,
transferList: [numbers.buffer]
};
}
在主线程上,我们传输输入类型化数组的缓冲区。然后,我们从返回的缓冲区重新创建 Float64Array。
// Module loaded in main thread
export function mapMultiplyFloat64Async(numbers, factor) {
let connection = null;
return workers.open("./calculator.js")
.then(function(conn) {
// Keep the connection reference to later close it.
connection = conn;
return connection.invoke("mapMultiplyFloat64", {
numbers: numbers,
factor: factor
});
})
.then(function(result) {
// close the connection after we are done.
connection.close();
connection = null;
return result;
});
}
// Invoke our method.
let floats = new Float64Array(5);
floats[0] = 0;
floats[1] = 2;
floats[2] = 4;
floats[3] = 6;
floats[4] = 8;
mapMultiplyFloat64Async(floats, 2)
.then(function(result) {
let resultFloats = new Float64Array(result);
console.log("Result:", resultFloats);
});
构造函数
-
new Connection()
-
方法概述
名称 | 返回值类值 | 描述 | 类 |
---|---|---|---|
Promise[] | 一种便捷方法,用于在每个 worker 上调用一个方法。 更多详情 | Connection | |
关闭对 workers 的现有连接实例。 更多详情 | Connection | ||
Promise | 在使用 worker 加载的远程模块上调用方法。 更多详情 | Connection |
方法详细说明
-
一种便捷方法,用于在每个 worker 上调用一个方法。
参数methodName String要在所有 workers 上调用的远程方法的名称。
data *optional作为远程方法的参数传递的唯一参数。
options Objectoptional指定附加选项的对象。有关此对象所需的属性,请参阅下面的对象规范表。
规范signal AbortSignaloptional中止远程方法执行的 AbortSignal。如果取消,则承诺将被拒绝,并返回一个名为
AbortError
的错误。另请参见 AbortController。返回类型 描述 Promise[] promise 数组,它根据每个 worker 上的执行结果进行解析。
-
close()
-
关闭对 workers 的现有连接实例。通知所有 workers 销毁连接实例并处置远程模块。
-
invoke(methodName, data, options){Promise}
-
在使用 worker 加载的远程模块上调用方法。
参数规范methodName String要在脚本中调用的方法的名称。
data *optional作为远程方法的参数传递的唯一参数。请参阅传递多个参数部分以将多个参数传递给远程方法。
options Objectoptional指定附加选项的对象。有关此对象所需的属性,请参阅下面的对象规范表。
规范transferList Transferable[]optionalTransferable 对象的数组。数组中的每个 transferable 对象在数据对象中都应有一个相应的条目。有关详细信息,请参阅使用 transferables 部分。
signal AbortSignaloptional中止远程方法执行的 AbortSignal。如果取消,则承诺将被拒绝,并返回一个名为
AbortError
的错误。另请参见 AbortController。返回类型 描述 Promise 解析为 worker 方法结果的 Promise。 示例const controller = new AbortController(); const signal = controller.signal; // invoke a function on a worker thread connection.invoke("myLongRunningRemoteFunction", { someParameter: 10 }, { signal }) .then((result) => { console.log(result); }) .catch((error) => { console.error(error); }); // if the call it takes more than 10 secs, abort: setTimeout(() => { controller.abort(); }, 10000);