Skip To ContentArcGIS for DevelopersSign In Dashboard

Connection

require(["esri/core/workers/Connection"], function(Connection) { /* code goes here */ });
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) {
  var sum = 0;

  for (var 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) {
  var 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.
  var numbers = params.numbers;
  var factor = params.factor;

  for (var 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) {
  var 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.

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.
  var numbers = new Float64Array(params.numbers);
  var 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) {
  var 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.
var 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) {
    var resultFloats = new Float64Array(result);
    console.log("Result:", resultFloats);
  });

Constructors

new Connection()

Method Overview

NameReturn TypeSummaryClass
Promise[]

A convenient method that invokes a method on each worker.

more details
more detailsConnection

Closes the existing connection instance to workers.

more details
more detailsConnection
Promise

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

more details
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:
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:
TypeDescription
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.

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:
TypeDescription
PromiseA 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);

API Reference search results

NameTypeModule
Loading...