async-magic

Promises FTW! A pure promised based, straight forward async library.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
async-magic
021.5.04 years ago7 years agoMinified + gzip package size for async-magic in KB

Readme

Build Status
async-magic
Promises FTW! A pure promised based, straight forward async library for Node.js >=7.6.
yarn add async-magic --save

Features

  • Convert callback based functions into promised based once (with named functions)
  • Advanced promised based control flows (parallel, series)
  • Run a set of promised functions in parallel with given number of maximum parallel tasks
  • Queue promised based function including arguments
  • Standalone, no external dependencies required
  • Designed to run with the pure power of native Promise, await and async function
  • No backward compatibility layer

API

promisify - Promisify a callback-based function promisifyAll - Promisify a set of callback-based functions parallel - Executes multiple PromiseResolver in parallel with given task limit series - Executes multiple PromiseResolver in series PromiseResolver - Utility function to cache a promised function including arguments for resolving. Required for advanced, promised based, control flows wait - Promise.all alias sleep - Intercept the current function execution Mutex - asynchronous Mutex lock pattern

promisify

Description: Promisify a callback-based function
Requirements:
Last function argument has to be the callback (Nodejs Standard) The first argument of the callback has to be a possible error (Nodejs Standard)
Syntax: fn:function = promisify(fn:function, [functionName:String])
Arguments:
fn:function - the callback based function which should be converted into a promise based functionName:String(optinal) - an optional name which is used as native js function name
Example:
const _asyncMagic = require('async-magic');
const _fs = require('fs');

// create promisified fs-stat. set "stat" as native function name
const fsStat = _asyncMagic.promisify(_fs, 'stat');

// use promisified version
(async function(){
    const fstats = await _fsStat(__filename);
    console.log('Size:', fstats.size);
})();

promisifyAll

Description: Promisify a set of callback-based functions
Syntax: promisifiedFunctionSet:Object = promisifyAll(functionSet:Object, functionNames:StringArray)
Arguments:
functionSet:Object - a set of functions identified by the objects keys functionNames:StringArray - a list of the object keys which should be promisified (names are also taken as native function names!)
Example:
Promisify some fs functions. Just as showcase, take a look at fs-magic - it is based on async-magic.
const _asyncMagic = require('async-magic');
const _fs = require('fs');

// list of fs methods to promisify
const fsApi = [
    'access',
    'appendFile',
    'chmod'
];

// create promisified fs version
const _fsPromised = _asyncMagic.promisifyAll(_fs, fsApi);

// use promisified version
(async function(){
    const fstats = await _fsPromised.stat(__filename);
    console.log('Size:', fstats.size);
})();

parallel

Description: Executes multiple PromiseResolver in parallel with given task limit
Syntax: results:array = parallel(resolvers:array, [limit:int=1000])
const _asyncMagic = require('async-magic');
const _fsMagic = require('fs-magic');
const PromiseResolver = _asyncMagic.PromiseResolver;

(async function(){
    // task list
    const tasks = [];
    
    // stat a large list of files 
    tasks.push(PromiseResolver(_fsMagic.stat, 'file1.txt'));
    tasks.push(PromiseResolver(_fsMagic.stat, 'file2.txt'));
    ...
    tasks.push(PromiseResolver(_fsMagic.stat, 'fileN.txt'));
    
    // resolves the promise with predefined arguments
    // limit the number of parallel executed promises to 100 (IO handle limitation)
    const stats = await _asyncMagic.parallel(tasks, 100);
})();

series

Description: Executes multiple PromiseResolver in series
Syntax: results:array = series(resolvers:array, [failOnError:boolean=true])
In case failOnError is not set, the resultset will contain the error object thrown during execution. Otherwise the executor will abort directly if an error has been thrown.
const _asyncMagic = require('async-magic');
const _fsMagic = require('fs-magic');
const PromiseResolver = _asyncMagic.PromiseResolver;

(async function(){
    // task list
    const tasks = [];
    
    // stat a large list of files 
    tasks.push(PromiseResolver(_fsMagic.stat, 'file1.txt'));
    tasks.push(PromiseResolver(_fsMagic.stat, 'file2.txt'));
    ...
    tasks.push(PromiseResolver(_fsMagic.stat, 'fileN.txt'));
    
    // resolves the promise with predefined arguments)
    const stats = await _asyncMagic.series(tasks);
})();

PromiseResolver

Description: Utility function to cache a promised function including arguments for resolving. Required for advanced, promised based, control flows
Syntax: p:PromiseResolver = PromiseResolver(fn:function, [...args:any])
const _asyncMagic = require('async-magic');
const _fsMagic = require('fs-magic');
const PromiseResolver = _asyncMagic.PromiseResolver;

(async function(){
    // caches the function with given arguments
    const task = PromiseResolver(_fsMagic.stat, 'file1.txt');
    
    // resolves the promise with predefined arguments
    const stat = await task.resolve();
})();

wait

Description: A Promise.all alias - waits until each promise has been completed or a single error occurs
Syntax: p:Promise = wait(promises:Array)
const _asyncMagic = require('async-magic');
const _fsMagic = require('fs-magic');

// stat multiple files at once
(async function(){
    const stats = await _asyncMagic.wait([
        _fsMagic.stat('file1.txt'),
        _fsMagic.stat('file2.txt'),
        _fsMagic.stat('file3.txt')
    ]);
})();

sleep

Description: Intercept the current function exection for a given time asynchronous (does not stop the global event loop!)
Syntax: p:Promise = sleep(time:int)
const _asyncMagic = require('async-magic');

(async function(){
    console('Hello..');

    // stop function execution for 1s (asynchronous!)
    await _asyncMagic.sleep(1000);

    console.log('World');
})();

Mutex

Description: Mutex lock pattern for asynchronous operations
Syntax: p:Mutex = new Mutex()
const _asyncMagic = require('async-magic');

(async function IOtask(){
   // create Mutex
    const mutex = new _asyncMagic.Mutex();

    // acquire lock
    await mutex.acquire();

    // do something exclusively
    await directIoOperation();

    // unlock
    mutex.release();
})();

FAQ

What is the difference between named and anonymous functions ? (promisify)
Named functions contains its function-name as immutable .name attribute. This is especially useful during debugging, because the stacktrace will display the plain-text function name instead of "anonymous"
const _asyncMagic = require('../async-magic');
const _fs = require('fs');

// create a unnamed (standard) version and a named one
const promisedStat = _asyncMagic.promisify(_fs.stat);
const namedPromisedStat = _asyncMagic.promisify(_fs.stat, 'stat');

// show function names (immutable .name attribute is set)
console.log(promisedStat.name); //=> anonymous
console.log(namedPromisedStat.name); //=> stat

Any Questions ? Report a Bug ? Enhancements ?

Please open a new issue on GitHub

License

async-magic is OpenSource and licensed under the Terms of The MIT License