Connection

AMD: require(["geoscene/core/workers/Connection"], (Connection) => { /* 代码 */ });
ESM: import Connection from "@geoscene/core/core/workers/Connection";
类: geoscene/core/workers/Connection
起始版本: GeoScene API for JavaScript 4.22

此类用于执行位于模块上的远程方法,这些模块通过 worker 框架加载到单独的线程中。

workers.open() 方法加载脚本并向主线程返回 Promise。解析后,您可以访问 Connection 的实例,该实例允许您通过 invoke()broadcast() 方法调用模块的方法。

调用远程方法

若要将工作委托给 worker,需要创建一个公开函数的模块或将由框架实例化的类。每个远程方法只能接受一个参数。参数值可以是任何基元类型,也可以是由结构化克隆算法处理的 JavaScript 对象,也可以是使用其中一个基元类型解析的 JavaScript Promise

例如,让我们创建一个简单的 worker 来计算数字数组的总和。

// 在 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 函数。

// 在主线程中加载的模块
export function getSumAsync(numbers) {
  let connection = null;

  return workers.open("./calculator.js")
    .then(function(conn) {
      // 保留连接引用以稍后关闭它。 
      connection = conn;

      return connection.invoke("getSum", numbers);
    })
    .then(function(result) {
      // 关闭连接
      connection.close();
      connection = null;

      return result;
    });
}

// 调用我们的方法。
getSumAsync([0, 2, 4, 6, 8])
  .then(function(result) {
    console.log("Result:", result);
  });

传递多个参数

如上所述,使用 worker 加载的远程方法只能接受一个参数。但是,要将多个参数传递给远程方法,请使用具有多个密钥值对的 JavaScript 对象。

下面的示例显示了一个函数,该函数将数字数组乘以一个因子。

// 在 worker 中加载模块: calculator.js
export function mapMultiply(params) {
  // params 有数字和因子值。
  let numbers = params.numbers;
  let factor = params.factor;

  for (let i = 0; i < numbers.length; i++) {
    numbers[i] *= factor;
  }

  return numbers;
}

若要调用此函数,需要将具有两个属性的对象传递到函数中。

// 在主线程中加载的模块
export function mapMultiplyAsync(numbers, factor) {
  let connection = null;

  return workers.open("./calculator.js")
    .then(function(conn) {
      // 保留连接引用以稍后关闭它。
connection = conn; // 调用 mapMultiply 并使用两个密钥值对传入对象。
return connection.invoke("mapMultiply", { numbers: numbers, factor: factor }); }) .then(function(result) { // 完成后关闭连接。
connection.close(); connection = null; return result; }); } // 调用我们的方法。 mapMultiplyAsync([0, 2, 4, 6, 8], 2) .then(function(result) { console.log("Result:", result); });

使用 transferables

Transferable 对象可用于在主线程和 worker 线程之间传输数据,以避免复制数据。使用此方法,对象的所有权将转移到其他上下文。使用此技术可使用 ArrayBuffers、MessagePortImageBitmap 传输大量内存。

Transferable 接口从技术上讲不再存在。 Transferable 对象的功能对象仍然存在,但是在更基础的级别实现(从技术上讲,使用 [Transferable] WebIDL 扩展属性)。 另请参阅 Transferable 对象

要将对象传输给 worker,请使用 invoke() 方法的 transferList 参数。 对于使用 transferable 对象返回或解析远程方法,返回的结果必须具有两个属性:resulttransferListresult 是一个对象 和 transferList transferable 对象的数组。 请注意,transferList 中的每个 transferable 对象都应该在 result 的对象结构中。

让我们重温前面的示例以探索 transferable 对象。

// 在 worker 中加载模块: calculator.js
export function mapMultiplyFloat64(params) {
  // numbers 参数是一个 ArrayBuffer
  // 我们从它创建一个类型化数组。
  let numbers = new Float64Array(params.numbers);
  let factor = params.factor;

  for (let i = 0; i < numbers.length; i++) {
    numbers[i] *= factor;
  }

  // 传回缓冲区
return { result: numbers.buffer, transferList: [numbers.buffer] }; }

在主线程上,我们传输输入类型化数组的缓冲区。然后,我们从返回的缓冲区重新创建 Float64Array

// 在主线程中加载的模块
export function mapMultiplyFloat64Async(numbers, factor) {
  let connection = null;

  return workers.open("./calculator.js")
    .then(function(conn) {
      // 保留连接引用以稍后关闭它。
      connection = conn;

      return connection.invoke("mapMultiplyFloat64", {
        numbers: numbers,
        factor: factor
      });
    })
    .then(function(result) {
      // 完成后关闭连接。
      connection.close();
      connection = null;

      return result;
    });
}

// 调用我们的方法。
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

方法详细说明

broadcast(methodName, data, options){Promise[]}

一种方便的方法,用于在每个 worker 上调用一个方法。

参数:
methodName String

要在所有 workers 上调用的远程方法的名称。

data *
optional

作为远程方法的参数传递的唯一参数。

options Object
optional

指定附加选项的对象。 有关此对象所需的属性,请参阅下面的对象规范表。

规范:
signal AbortSignal
optional

AbortSignal 用于中止远程方法的执行。 如果取消,promise 将被拒绝,并出现名为 AbortError 的错误。 另请参阅 AbortController

返回值:
类型 描述
Promise[] 一组 Promise,这些 Promise 与每个 worker 上的执行结果一起解析。
close()

关闭 workers 现有连接实例。 通知所有 workers 销毁连接实例并处置远程模块。

invoke(methodName, data, options){Promise}

调用加载了 worker 的远程模块上的方法

参数:
规范:
methodName String

要在脚本中调用的方法的名称。

data *
optional

作为远程方法的参数传递的唯一参数。请参阅传递多个参数部分以将多个参数传递给远程方法。

options Object
optional

指定附加选项的对象。 有关此对象所需的属性,请参阅下面的对象规范表。

规范:
transferList Transferable[]
optional

Transferable 对象的数组。数组中的每个 transferable 对象在数据对象中都应有一个相应的条目。有关详细信息,请参阅使用 transferables 部分。

signal AbortSignal
optional

AbortSignal 用于中止远程方法的执行。 如果取消,promise 将被拒绝,并出现名为 AbortError 的错误。 另请参阅 AbortController

返回值:
类型 描述
Promise 解析为 worker 方法结果的 Promise 。
示例代码:
const controller = new AbortController();
const signal = controller.signal;

// 在 worker 线程上调用函数
connection.invoke("myLongRunningRemoteFunction", { someParameter: 10 }, { signal }) .then((result) => { console.log(result); }) .catch((error) => { console.error(error); }); // 如果调用时间超过 10 秒,则中止:
setTimeout(() => { controller.abort(); }, 10000);

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.