createBatcher collects single-item load() calls for a few milliseconds and sends them as one batched request: 100 getUser(id) calls become one SELECT ... WHERE id IN (...). It is DataLoader’s (and bottleneck’s Batcher) idea, with two additions: each batch runs through a resilience pipeline as a unit, and cancellation works per caller. Use it to fix N+1 queries in GraphQL resolvers or fan-out code, or to fit a bulk API. Don’t use it when calls are rare (each one waits up to maxWait for company), or when the backend has no batch endpoint.
Polly-style builder with a shortcut for every strategy: addRetry(), addTimeout(), addCircuitBreaker(), …
Convenient, but it bundles every strategy. For the smallest browser bundle use PipelineBuilder with
retryStrategy(), timeoutStrategy(), … instead; the two are interchangeable.
The type parameters track which errors the pipeline can raise, for pipeline.settle() + Outcome.match().
Loads a batch. Return one result per item, in order, or a Map by key. A result that is an Error rejects only that item.
Gets the pipeline's context: pass context.signal on to your I/O.
run: async (
ids: string[]
ids, {
signal: AbortSignal
Aborted when the caller cancels, or when a strategy (timeout, hedging) gives up on this execution.
signal }) => {
const
constrows:User[]
rows=await
constdb: {
usersByIds(ids:string[], options: {
signal:AbortSignal;
}):Promise<User[]>;
}
db.
functionusersByIds(ids:string[], options: {
signal:AbortSignal;
}):Promise<User[]>
usersByIds(
ids: string[]
ids, {
signal: AbortSignal
signal });
returnnew
var Map:MapConstructor
new <string, User>(iterable?:Iterable<readonly [string, User]> |null|undefined) =>Map<string, User> (+3 overloads)
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map((
u: User
u) => [
u: User
u.
User.id: string
id,
u: User
u]));
},
});
// Three loads, two distinct ids: one query for ['1', '2'].
const [
consta:User
a,
constb:User
b,
constc:User
c] =await
var Promise:PromiseConstructor
Represents the completion of an asynchronous operation
Queues the item for the next batch. Aborting signal (default: the ambient pipeline's signal) rejects this call and, until the batch starts, drops the item from it.
Queues the item for the next batch. Aborting signal (default: the ambient pipeline's signal) rejects this call and, until the batch starts, drops the item from it.
Queues the item for the next batch. Aborting signal (default: the ambient pipeline's signal) rejects this call and, until the batch starts, drops the item from it.
collecting (≤ maxWait)run(items), one call per batchload() joinsresolved idsrejected (u6 has no row)Colour = batch. Each dot is one load(); equal ids in a batch share one slot (dedupe by key), so ×n counts distinct ids.
0 loads → 0 batches with 0 distinct ids; average wait per load 0 ms.
A length mismatch rejects every item of the batch.
A Map (needs key)
By key
That item rejects with Batcher: no result for key ....
Either way, a result that is an Error instance rejects only that item; the others resolve. If run throws (after the pipeline’s retries), every item of the batch rejects with that error.
Loads a batch. Return one result per item, in order, or a Map by key. A result that is an Error rejects only that item.
Gets the pipeline's context: pass context.signal on to your I/O.
run: async (
skus: string[]
skus:string[], {
signal: AbortSignal
Aborted when the caller cancels, or when a strategy (timeout, hedging) gives up on this execution.
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@param ― callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
@param ― thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map((
p: Price |null
p,
i: number
i) =>
p: Price |null
p??new
var Error:ErrorConstructor
new (message?:string, options?:ErrorOptions) =>Error (+1 overload)
Queues the item for the next batch. Aborting signal (default: the ambient pipeline's signal) rejects this call and, until the batch starts, drops the item from it.
load('sku-1'); // rejects only if this sku is unknown
Without key, every load() gets its own slot, even for equal items.
A batch is shared by many callers, so one caller can’t cancel it for the others.
Before the batch is sent, aborting a caller’s signal rejects that load() with the abort reason and removes its item, unless another caller is waiting on the same key.
After the batch is sent, aborting rejects that caller’s load() only. The batch keeps running for everyone else.
Default signal. Without signal, load() uses the signal of the pipeline execution it is called from (the ambient context), if any. So a load() inside pipeline.execute() gives up when that execution times out.
The batch has its own signal.run doesn’t run inside the execution that happened to trigger the flush, so that caller’s deadline doesn’t cancel the batch. Put a timeout in the batcher’s own pipeline.