Asynchronous coordination for JavaScript and TypeScript.
DEPRECATED: This package has been deprecated in favor of the following packages that replace it:]
@esfx/cancelable:
CancelError@esfx/canceltoken:
is nowCancellationTokenCancelTokenis nowCancellationTokenSourceCancelSource/CancelToken.source()@esfx/async-manualresetevent:
is nowManualResetEventAsyncManualResetEvent@esfx/async-autoresetevent:
is nowAutoResetEventAsyncAutoResetEvent@esfx/async-semaphore:
is nowSemaphoreAsyncSemaphore@esfx/async-countdown:
is nowCountdownEventAsyncCountdownEvent@esfx/async-barrier:
is nowBarrierAsyncBarrier@esfx/async-readerwriterlock:
is nowReaderWriterLockAsyncReaderWriterLock@esfx/async-deferred:
Deferred@esfx/async-queue:
AsyncQueue@esfx/async-stack:
AsyncStack@esfx/async-delay:
delay(msec, value?)- NOTE: There are no replacements for
AsyncBoundedQueueorPulsar, they have been deprecated.
This library contains a number of coordination primitives to assist in asynchronous application development in JavaScript and TypeScript. This includes useful additions for building complex asynchronous logic including:
- Cancellation [Sample, API Reference]
- Coordination [Sample, API Reference]
- Scheduling [Sample, API Reference]
For the latest version:
npm install prex
API Reference: Cancellation
The CancellationTokenSource and CancellationToken primitives allow you to create asynchronous operations that can be canceled externally. The following is an example of a function used to download a file asynchronously that can be canceled:
import * as http from "http";
import * as fs from "fs";
import { CancellationTokenSource, CancellationToken } from "prex";
function downloadFile(from: string, to: string, token = CancellationToken.none) {
return new Promise<void>((resolve, reject) => {
const request = http.get(from);
// abort the request if canceled.
const registration = token.register(() => {
request.abort();
reject(new Error("Operation canceled."));
});
request.on("error", err => {
registration.unregister();
reject(err);
});
request.on("response", (response: http.IncomingMessage) => {
response
.pipe(fs.createWriteStream(to))
.on("error", err => {
registration.unregister();
reject(err);
})
.on("end", () => {
registration.unregister();
resolve();
});
});
});
}
async function main() {
const source = new CancellationTokenSource();
// cancel the source if the file takes more than one second to download
setTimeout(() => source.cancel(), 1000);
await downloadFile("http://tempuri.org/some/file", "file", source.token);
}API Reference: Coordination
A Semaphore can be used to protect access to a critical section of your code when you must limit access across multiple async operations. The following is an example of two functions which both need exclusive access to a single resource but could possibly be preempted when suspended while awaiting an asynchronous operation:
import { Semaphore } from "prex";
const criticalResource = new Semaphore(1);
async function updateCriticalLocalResource() {
// Acquire a lock on the critical resource
await criticalResource.wait();
// Make local changes...
// await a network resources
await postUpdateToNetworkResource(changes);
// release the lock
criticalResource.release();
}
async function deleteCriticalLocalResource() {
// Acquire a lock on the critical resource
await criticalResource.wait();
// Make local changes...
// await a network resources
await postUpdateToNetworkResource(changes);
// release the lock
criticalResource.release();
}
declare function postUpdateToNetworkResource(changes): Promise<void>;A Barrier can be used to coordinate complex async operations:
import { Barrier } from "prex";
const barrier = new Barrier(/*participantCount*/ 3);
async function processNpcAI() {
while (true) {
// process AI activities...
await barrier.signalAndWait();
}
}
async function processGameRules() {
while (true) {
// process game rules
await barrier.signalAndWait();
}
}
async function processGameInput() {
while (true) {
// process user input
await barrier.signalAndWait();
}
}API Reference: Scheduling
An AsyncQueue is a useful primitive for scheduling asynchronous work:
import { AsyncQueue } from "prex";
const workItems = new AsyncQueue();
function queueUserWorkItem(action: () => void) {
workItems.put(action);
}
async function processWorkItems() {
while (true) {
const action = await workItems.get();
try {
action();
}
catch (e) {
console.error(e);
}
}
}Copyright (c) Microsoft Corporation. Licensed under the Apache License, Version 2.0.
See LICENSE file in the project root for details.