Code Examples for Reading 22
Download
You can also download a ZIP file containing this code.
timeout.ts
import assert from 'assert';
import Q from 'q';
/**
* @param milliseconds duration to wait
* @returns a promise that fulfills no less than `milliseconds` after timeout() was called
*/
async function timeout(milliseconds:number):Promise<void> {}
// implemented three ways below:
// version 1:
// using a Q.Deferred object,
// which consists of a promise and its resolve and reject operations:
async function timeout1(milliseconds:number):Promise<void> {
const deferred: Q.Deferred<void> = Q.defer();
setTimeout(function() {
deferred.resolve(); // this mutates deferred.promise into the fulfilled state
// or we could call deferred.reject(new Error(...)) to reject the promise instead
}, milliseconds);
return deferred.promise;
}
// version 2:
// implemented using Promise constructor,
// explicitly pulling out its resolve and reject operations:
async function timeout2(milliseconds:number):Promise<void> {
let resolvePromise;
let rejectPromise;
const promise = new Promise<void>(function(resolve, reject) {
resolvePromise = resolve;
rejectPromise = reject;
});
assert(resolvePromise);
setTimeout(resolvePromise, milliseconds);
return promise;
}
// version 3:
// implemented using Promise constructor, more concisely
async function timeout3(milliseconds:number):Promise<void> {
return new Promise<void>(function(resolve, reject) {
setTimeout(resolve, milliseconds);
})
}
TinyQueue.ts
import assert from 'assert';
import { describe, it } from 'mocha';
import Q from 'q';
/**
* Asynchronous queue of size 1.
*/
export class TinyQueue<E> {
private element: E|undefined = undefined;
private waitingToPut: Array<Q.Deferred<void>> = [];
private waitingToTake: Array<Q.Deferred<void>> = [];
// RI:
// if any puts are waiting (waitingToPut.length > 0), then queue is full (element !== undefined)
// if any takes are waiting (waitingToTake.length > 0), then queue is empty (element === undefined)
/**
* Put an element onto this queue.
* @param elt element to put on queue
* @returns promise that fulfills once the element gets onto the queue
*/
public async put(elt:E):Promise<void> {
console.log('put:', elt);
if (this.element !== undefined) {
// wait until the queue is empty
const deferred: Q.Deferred<void> = Q.defer();
this.waitingToPut.push(deferred);
await deferred.promise;
}
assert(this.element === undefined);
this.element = elt;
// notify first take() call that is waiting, if any
const deferred = this.waitingToTake.shift();
if (deferred) {
deferred.resolve();
}
}
/**
* Remove and return element from this queue.
* @returns element taken from queue
*/
public async take():Promise<E> {
console.log('take');
if (this.element === undefined) {
// wait until the queue has an element
const deferred: Q.Deferred<void> = Q.defer();
this.waitingToTake.push(deferred);
await deferred.promise;
}
const elt = this.element;
assert(elt !== undefined);
this.element = undefined;
// notify first put() call that is waiting, if any
const deferred = this.waitingToPut.shift();
if (deferred) {
deferred.resolve();
}
return elt;
}
}