import { filter, createAbortError, isAbortError, ignoreAbortErrors, eachAlways } from "@arcgis/core/core/promiseUtils.js";
Since
ArcGIS Maps SDK for JavaScript 4.2

Various utilities and convenience functions for working with promises.

Type definitions

FilterPredicateCallback

Type definition
Type parameters
<T>

Callback to be called for each entry of an array to be filtered.

Parameters

ParameterTypeDescriptionRequired
value
T

The value of the array entry.

index

The index of the entry within the array.

Returns
Promise<boolean>

A promise that resolves to a boolean value, indicating whether the entry should be kept in the filtered array.

EachAlwaysResult

Type definition
Type parameters
<T>

The result object for a promise passed to eachAlways().

promise

Property
Type
Promise

The promise that has been fulfilled.

value

Property
Type
T | undefined

The value with which the promise resolved. Defined only if the promise resolved.

error

Property
Type
any | undefined

The error with which the promise rejected. Defined only if the promise rejected.

AbortOptions

Type definition

Abort options that can be passed into an asynchronous method to allow termination.

signal

Property
Type
AbortSignal | null | undefined

Signal object that can be used to abort the asynchronous task. The returned promise will be rejected with an Error named AbortError when an abort is signaled. See also AbortController for more information on how to construct a controller that can be used to deliver abort signals.

Example:

const controller = new AbortController();
const signal = controller.signal;
esriRequest(url, { signal })
.then((response) => {
// The request went OK
})
.catch((err) => {
if (err.name === 'AbortError') {
console.log('Request aborted');
} else {
console.error('Error encountered', err);
}
});
// Abort requests that are aware of the controller's signal
controller.abort();

Functions

filter

Function
Type parameters
<T>

A convenience utility method for filtering an array of values using an asynchronous predicate function.

Signature
filter <T>(input: T[], predicate: FilterPredicateCallback<T>): Promise<T[]>

Parameters

ParameterTypeDescriptionRequired
input
T[]

The array of input values to filter.

predicate

A predicate function returning a promise. Only array entries for which the returned promise contains true are kept.

Returns
Promise<T[]>

A promise containing an array of values that passed the predicate check.

createAbortError

Function

Creates a special error object which is used to signal aborted requests in promise chains. Promises that are rejected due to abort signals should reject with this kind of error.

Signature
createAbortError (): Error
Returns
Error

A special error object that signals an aborted request.

Example
// Request multiple files and return results in an array
function requestMultiple(urls, abortSignal) {
// Fire off requests
let promises = urls.map(url => request(url, { signal: abortSignal });
// Wait until all requests have either resolved or rejected
promiseUtils.eachAlways(urls)
.then(results => {
if (abortSignal && abortSignal.aborted) {
// If the user has triggered the abortSignal, all requests will react and reject. eachAlways resolves with
// an array that contains the reject error for each request. Instead of returning this array as a result, we
// should reject the promise returned to the user with an abort error.
throw promiseUtils.createAbortError();
}
return results;
});
}

isAbortError

Function

Check if the provided error object is the special kind of error with which promises are rejected when they are aborted.

Signature
isAbortError (error: Error): boolean

Parameters

ParameterTypeDescriptionRequired
error

The error object to test.

Returns
boolean

true if the error is an abort error, false otherwise.

Example
// This function fetches a document via HTTP and logs its content to the console once available
function logHTTPDocumentToConsole(url, abortSignal) {
// Pass the abort signal into `request` to make it cancelable
request(url, { signal: abortSignal })
.then((response) => {
console.log(response.data);
})
.catch((error) => {
if (!promiseUtils.isAbortError(error)) {
// Only log request failures and ignore cancellations
console.error("request error", error);
}
});
}
let controller = new AbortController();
let url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer";
logHTTPDocumentToConsole(url, controller.signal);
// Cancel the request
controller.abort();

ignoreAbortErrors

Function
Type parameters
<T>
Since
ArcGIS Maps SDK for JavaScript 4.32

Catches and "drops" abort errors. All other errors are re-thrown. The returned promise resolves with undefined if an abort error occurred.

Signature
ignoreAbortErrors <T>(promise: Promise<T>): Promise<T | undefined>

Parameters

ParameterTypeDescriptionRequired
promise

The promise to catch abort errors on.

Returns
Promise<T | undefined>

A promise that resolves with the original promise's value, or undefined if an abort error occurred.

eachAlways

Function

Convenience utility method to wait for a number of promises to either resolve or reject. The resulting promise resolves to an array of result objects containing the promise and either a value if the promise resolved, or an error if the promise rejected. This is similar to the native Promise.allSettled method with the additional feature of taking an object parameter.

Signature
eachAlways (promises: Promise<any>[] | any): Promise<EachAlwaysResult<any>[] | any>

Parameters

ParameterTypeDescriptionRequired
promises
Promise<any>[] | any

Array of promises, or object where each property is a promise.

Returns
Promise<EachAlwaysResult<any>[] | any>

If called with an array of promises, resolves to an array of result objects containing the original promise and either a value (if the promise resolved) or an error (if the promise rejected). If called with an object where each property is a promise, then resolves to an object with the same properties where each property value is a result object.

Example
const controller = new AbortController();
// Query for the number of features from
// multiple feature layers
function queryLayerFeatureCount(whereClauses) {
// pass each whereClause item into callback function
return promiseUtils.eachAlways(whereClauses.map(function (whereClause) {
return layer.queryFeatureCount(whereClause, {
signal: controller.signal
});
}));
}
queryLayerFeatureCount(whereClauses).then(function(eachAlwaysResults) {
eachAlwaysResults.forEach(function(result) {
// If a Promise was rejected, you can check for the rejected error
if (result.error) {
console.log("There was an error in your query.", result.error);
}
// The results of the Promise are returned in the value property
else {
console.log("The number of features are: " + result.value);
}
});
});

debounce

Function
Type parameters
<T>
Since
ArcGIS Maps SDK for JavaScript 4.12

A utility for ensuring an input function is not simultaneously invoked more than once at a time. This is useful for highly interactive applications such as those that execute statistic queries on mouse-move or mouse-drag events. Rather than execute the query for each such event, you can "debounce", or cancel the function execution, until the previous execution of the same function call finishes. This improves the performance and user experience of such applications.

See also
Signature
debounce <T>(callback: T): T

Parameters

ParameterTypeDescriptionRequired
callback
T

A function to prevent executing during the execution of a previous call to the same function. This is typically a function that may be called on mouse-move or mouse-drag events.

Returns
T

A function with the same signature as the callback.

Example
// Queries a layer for the count of features that intersect a
// 1 km buffer of the pointer location. The debounce() method
// prevents the updateStatistics function from executing before
// a previous invocation of the same function finishes.
const updateStatistics = promiseUtils.debounce(function (geometry) {
return layerView.queryFeatures({
geometry,
distance: 1,
units: "kilometers",
outStatistics: [{
onStatisticField: "*",
outStatisticFieldName: "feature_count",
statisticType: "count"
}]
}).then(function(featureSet) {
console.log(`Feature Count: ${featureSet.features[0].attributes["feature_count"]}`);
});
});
view.on("drag", (event) => updateStatistics(view.toMap(event)));