diff --git a/asyncblock/asyncblock-tests.ts b/asyncblock/asyncblock-tests.ts new file mode 100644 index 0000000000..57328e13a5 --- /dev/null +++ b/asyncblock/asyncblock-tests.ts @@ -0,0 +1,140 @@ +/// +/// + +import asyncblock = require('asyncblock'); +import fs = require('fs'); + + +// Sleeping in series +asyncblock((flow: asyncblock.IFlow) => { + console.time('time'); + + setTimeout(flow.add(), 1000); + flow.wait(); //Wait for the first setTimeout to finish + + setTimeout(flow.add(), 2000); + flow.wait(); //Wait for the second setTimeout to finish + + console.timeEnd('time'); //3 seconds +}); + +// Trapping results +asyncblock((flow) => { + var path1 = '', path2 = ''; + //Start two parallel file reads + fs.readFile(path1, 'utf8', flow.set('contents1')); + fs.readFile(path2, 'utf8', flow.set('contents2')); + + //Print the concatenation of the results when both reads are finished + console.log(flow.get('contents1') + flow.get('contents2')); + + var paths: string[] = []; + //Wait for a large number of tasks + for(var i = 0; i < 100; i++){ + //Add each task in parallel with i as the key + fs.readFile(paths[i], 'utf8', flow.add(i)); + } + + //Wait for all the tasks to finish. Results is an object of the form {key1: value1, key2: value2, ...} + var results = flow.wait(); + + var path = ''; + //One-liner syntax for waiting on a single task + var contents = flow.sync( fs.readFile(path, 'utf8', flow.callback()) ); + + //See overview & API docs for more extensive description of techniques +}); + +// Error handling +var asyncTask = (callback: (err: any) => void) => { + asyncblock((flow) => { + flow.errorCallback = callback; //Setting the errorCallback is the easiest way to perform error handling. If erroCallback isn't set, and an error occurs, it will be thrown instead of returned to the callback + + var path = ''; + fs.readFile(path, 'utf8', flow.add()); //If readFile encountered an error, it would automatically get passed to the callback + var contents = flow.wait(); + + console.log(contents); //If an error occured above, this code won't run + }); +}; + +// Returning results +var asyncTask2 = (callback: (err: any, res: string) => void) => { + asyncblock((flow) => { + var path = ''; + var contents = flow.sync( fs.readFile(path, 'utf8', flow.callback()) ); //If readFile encountered an error, it would automatically get passed to the callback + + return contents; //Return the value you want to be passed to the callback + }, callback); //The callback can be specified as the 2nd arg to asyncblock. It will be called with the value returned from the asyncblock as the 2nd arg. + //If an error occurs, the callback will be called with the error as the first argument. +}; + + +// Sample +asyncblock.nostack((flow) => { + fs.readFile('path1', 'utf8', flow.add('first')); + fs.readFile('path2', 'utf8', flow.add('second')); + + //Wait until done reading the first and second files, then write them to another file + fs.writeFile('path3', flow.wait('first') + flow.wait('second'), flow.add()); + flow.wait(); //Wait on all outstanding tasks + + fs.readFile('path3', 'utf8', flow.add('data')); + + console.log(flow.wait('data')); //Print the 3rd file's data + console.log('all done'); +}); + + +// Formatting results +(function() { + +var asyncTask = function(callback: (err: any, res1: number, res2: number, res3: number) => void) { + process.nextTick(function() { + callback(null, 1, 2, 3); + }); +} + +asyncblock(function(flow) { + asyncTask(flow.add()); + + var result = flow.wait(); + console.log(result); // Prints 1 +}); + +asyncblock(function(flow) { + asyncTask(flow.add(['first', 'second', 'third'])); + + var result = flow.wait(); + console.log(result); // Prints { first: 1, second: 2, third: 3 } + + asyncTask(flow.add('key1', ['first', 'second', 'third'])); + asyncTask(flow.add('key2', ['a', 'b', 'c'])); + var result = flow.wait(); + console.log(result); // Prints { key1: { first: 1, second: 2, third: 3 }, key2: { a: 1, b: 2, c: 3} } +}); + +})(); + + +// Task timeouts +(function() { + +asyncblock(function(flow){ + setTimeout(flow.add({timeout: 1000, timeoutIsError: false}), 2000); + flow.wait(); //The fiber will yield here for 1 second, then continue + + //Code here will run +}); + +asyncblock(function(flow){ + flow.timeoutIsError = false; + + setTimeout(flow.add({timeout: 1000}), 2000); + flow.wait(); //The fiber will yield here for 1 second, then continue + + //Code here will run +}); + +})(); + diff --git a/asyncblock/asyncblock.d.ts b/asyncblock/asyncblock.d.ts new file mode 100644 index 0000000000..d1cd5e0052 --- /dev/null +++ b/asyncblock/asyncblock.d.ts @@ -0,0 +1,51 @@ +// Type definitions for asyncblock 2.1.23 +// Project: https://github.com/scriby/asyncblock +// Definitions by: Hiroki Horiuchi +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +declare module "asyncblock" { + function asyncblock(f: (flow: asyncblock.IFlow) => void, callback?: (err: any, res: T) => void): void; + + module asyncblock { + export function nostack(f: (flow: asyncblock.IFlow) => void, callback?: (err: any, res: T) => void): void; + + export interface IFlow { + add(responseFormat?: string[]): any; + add(key: string, responseFormat?: string[]): any; + add(key: number, responseFormat?: string[]): any; + add(options: IFlowOptions): any; + callback(responseFormat?: string[]): any; + callback(key: string, responseFormat?: string[]): any; + callback(key: number, responseFormat?: string[]): any; + callback(options: IFlowOptions): any; + sync(f: void): T; + wait(key?: string): T; + wait(key?: number): T; + + get(key: string): T; + set(key: string, responseFormat?: string[]): any; + set(options: IFlowOptions): any; + del(key: string): void; + + maxParallel: number; + errorCallback: (err: any) => void; + taskTimeout: number; + timeoutIsError: boolean; + } + + export interface IFlowOptions { + ignoreError?: boolean; // default false + key?: string; // string | number + responseFormat?: string[]; + timeout?: number; + timeoutIsError?: boolean; + dontWait?: boolean; + firstArgIsError?: boolean; // default false + } + + } + + export = asyncblock; +} +