Promise Extensions for JavaScript (prex)
Asynchronous coordination for JavaScript and TypeScript.
DEPRECATED: This package has been deprecated in favor of the following packages that replace it:]
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:
Installing
For the latest version:
npm install prex
Documentation
Samples
Cancellation
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);
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();
setTimeout(() => source.cancel(), 1000);
await downloadFile("http://tempuri.org/some/file", "file", source.token);
}
Coordination
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() {
await criticalResource.wait();
await postUpdateToNetworkResource(changes);
criticalResource.release();
}
async function deleteCriticalLocalResource() {
await criticalResource.wait();
await postUpdateToNetworkResource(changes);
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( 3);
async function processNpcAI() {
while (true) {
await barrier.signalAndWait();
}
}
async function processGameRules() {
while (true) {
await barrier.signalAndWait();
}
}
async function processGameInput() {
while (true) {
await barrier.signalAndWait();
}
}
Scheduling
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);
}
}
}
License
Copyright (c) Microsoft Corporation.
Licensed under the Apache License, Version 2.0.
See LICENSE file in the project root for details.