prex-es5
v0.4.2
Published
Async coordination primitives and extensions on top of ES6 Promises
Downloads
34
Maintainers
Readme
Promise Extensions for JavaScript (prex)
Asynchronous coordination for JavaScript and TypeScript.
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]
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);
// 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(1000, () => source.cancel());
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() {
// 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();
}
}
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.