Connection

AMD: require(["esri/core/workers/Connection"], (Connection) => { /* code goes here */ });
ESM: import Connection from "@arcgis/core/core/workers/Connection";
Class: esri/core/workers/Connection
Since: ArcGIS API for JavaScript 4.2

This class is used to execute remote methods located on the module loaded into a separate thread via the workers framework.

The workers.open() method loads the script and returns a Promise to the main thread. Once resolved, you gain access to an instance of Connection, which allows you to call methods of the module via invoke() or broadcast() methods.

Invoking a remote method

To delegate work to a worker, you need to create a module that exposes functions or a class that will be instantiated by the framework. Each remote method can accept one parameter only. The parameter value can be any primitive type, or JavaScript object handled by the structured clone algorithm, or a JavaScript Promise that resolves with one of them.

For example, let's create a simple worker that calculates the sum of an array of numbers.

// 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;
}

Now we load the calculator module into a worker and invoke its getSum function.

// 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);
  });

Passing multiple parameters

As mentioned above, the remote methods loaded with worker can only accept one parameter. However, to pass multiple parameters to the remote method, use a JavaScript object with multiple key-value pairs.

The example below shows a function that multiplies an array of numbers by a factor.

// 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;
}

To invoke this function, an object with two properties is passed into the function.

// 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);
  });

Using transferables

Transferable objects can be used to transfer data between main and worker thread to avoid copying the data. With this approach, the ownership of the object is transferred to the other context. Use this technique to transfer large chuck of memory with ArrayBuffers, a MessagePort, or an ImageBitmap.

Note

The Transferable interface technically no longer exists. The functionality of Transferable objects still exists, however, but is implemented at a more fundamental level (technically speaking, using the [Transferable] WebIDL extended attribute). See also getdocs.org.

To transfer an object to the worker, use the transferList parameter of the invoke() method. For the remote method to return or resolve with a transferable object, the result returned must have two properties: result and transferList, result being an object and transferList the array of transferable objects. Note that every transferable object in transferList should be in the object structure of result.

Let's revisit the previous example to explore transferable objects.

// 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]
  };
}

On the main thread, we transfer the input typed array's buffer. Then we recreate a Float64Array back from the returned buffer.

// 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);
  });

Constructors

new Connection()

Method Overview

Name Return Type Summary Class
Promise[]more details

A convenient method that invokes a method on each worker.

more detailsConnection
more details

Closes the existing connection instance to workers.

more detailsConnection
Promisemore details

Invokes a method on the remote module loaded with the worker.

more detailsConnection

Method Details

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

A convenient method that invokes a method on each worker.

Parameters:
methodName String

The name of the remote method to invoke on all workers.

data *
optional

The unique parameter passed as argument of the remote method.

options Object
optional

An object specifying additional options. See the object specification table below for the required properties of this object.

Specification:
signal AbortSignal
optional

An AbortSignal to abort the executions of the remote method. If canceled, the promise will be rejected with an error named AbortError. See also AbortController.

Returns:
Type Description
Promise[] An array of promises that resolves with the result of the execution on each worker.
close()

Closes the existing connection instance to workers. Notifies all workers to destroy the connection instance and dispose the remote module.

invoke(methodName, data, options){Promise}

Invokes a method on the remote module loaded with the worker.

Parameters:
Specification:
methodName String

The name of the method to be invoked in the script.

data *
optional

The unique parameter passed as argument of the remote method. See Passing multiple parameters section to pass more than one parameter to the remote method.

options Object
optional

An object specifying additional options. See the object specification table below for the required properties of this object.

Specification:
transferList Transferable[]
optional

An array of Transferable objects. Each transferable object in the array should have a corresponding entry in the data object. See Using transferables section for more information.

signal AbortSignal
optional

An AbortSignal to abort the execution of the remote method. If canceled, the promise will be rejected with an error named AbortError. See also AbortController.

Returns:
Type Description
Promise A Promise that resolves to the result of the method of the worker.
Example:
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);

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