Giter Site home page Giter Site logo

potem's Introduction

potem

Modern, very fast, lightweight, async, promise-like class

Learn from the examples:) You can find many of them in the spec/ directory.

Version 3

Version 3 is not compatible with version 1.x nor with 2.x. Potem class has been converted to "potem" function. Now you are able to then functions without "then" keyword because potem function returns itself.

install

npm install potem

sync usage

var potem = require('potem').potem;
var result = 0;

potem(function () {
    return 1;
})
(function (n) {
    return n + 1;
})
(function (n) {
    return n * 2;
})
(function (n) {
    result = n;
})
.fin(function (n) {
    expect(result).toBe(4);
});

Basic async example

var potem = require('potem').potem
var fs = require('fs');

var p = potem()
    .then(function () {
        //p.pause() method returns a "resume" callback and pauses current execution.
        fs.readdir('./spec', p.pause());
    })
    .then(function (err, files) {
        if (err) { throw err; }
        //we've got files array
    })
    .error(function(err) {
      //do something with the (thrown) error
    });

Basic async example using argument converters

var potem = require('potem').potem;
var fs = require('fs');

var p = potem()
    .then(function () {
        //p.pause() method returns a "resume" callback and pauses current execution.
        fs.readdir('./spec', p.pause(1, throwArg));
    })
    .then(function (err, files) {
        //we've got files array
    })
    .error(function(err) {
      //do something with the (thrown) error
    });

async usage (read directory content)

var potem = require('potem').potem;
var fs = require('fs');

var p = potem
    .then(function () {
        //p.pause() method returns a "resume" callback and pauses current execution.
        fs.readdir('./spec', p.pause());
    })
    .then(function (err, files) {
        if (err) { throw err; }
        var next = p.pause(files.length, p.throwArg);

        files.forEach(function (file) {
            console.log('file', file);
            fs.readFile('./spec/' + file, next);
        });
    })
    .then([function () {
        return Array.prototype.join.call(arguments, '');
    }])
    .then(function (result) {
        dirContent = result;
    })
    .error(function (err) {
        console.log('catch', err.stack);
    });

more examples

For more examples check out the spec/ directory

API

.then(callback:(...args))

add callback function to the call stack. Take last returned argument as an input. Or if the execution was paused take last resume() (resume is returned from .pause()) function arguments as its own arguments.

.then([...callbacks:(..arrOfArgs)[]])

In this case (if array of callbacks are arguments) every callback will be called with all the arguments that ware passed to resume() function (or last return statement)

for example:

var potem = require('potem').potem;
var fs = require('fs');

var p = potem
  .then(function () {
    fs.exists('file.txt', p.pause());
    fs.readFile('file2.txt', p.pause(1, p.throwArg));
  })
  .then([function (existsArgs, readFileArgs) {
    //existsArgs[0] => boolean (true if file.txt exists)
    //readFileArgs[0] => Buffer (the content of a file)
  }])
  .error(function (err) {
    //err => Error (if readFile has an error as a first argument
  });

.error(errCallback:(err))

Set the error handler. If any of "then" functions thew an error then this function will be called. If an error will be called in this function then it can be cought in the next .error() of .fin() function.

.fin(callback:(...args))

It's like .then() but will be called even if an error was thrown.

.pause(pauseCounter:number, ...argumentConverters)

Returns the resume() function and pauses the execution. If you specify the pauseCounter parameter then the execution will be paused for pauseCounter number of times (resume() function would have to be called pauseCounter times for the next .then() to be called).

You can specify any number of argument converters. Argument converters do something with the arguments and after the conversion they pass the result to the next .then() function.

.stdPause(pauseCounter:number)

Shorthand for .pause(pauseCounter, p.throwArg); for callbacks with standard (usually node) call signature.

.passArg argument converter

This argument converter does nothing. It's usefull if you want to do something with arguments that are passed on the later positions.

var potem = require('potem').potem;

var func = function (callback) {
  callback(1, 2, 3);
}

var p = potem
  .then(function () {
    func(p.pause(1, p.passArg, p.skipArg);
  })
  .then(function (arg1, arg2) {
    //arg1 => 1
    //arg2 => 3 (because value "2" is skipped)
  });

.skipArg argument converter

Removes the argument on the current position from the argument set

var potem = require('potem').potem;

var func = function (callback) {
  callback(1, 2, 3);
}

var p = potem()
  .then(function () {
    func(p.pause(1, p.skipArg);
  })
  .then(function (arg1, arg2) {
    //arg1 => 2 (because value "1" is skipped)
    //arg2 => 3
  });

.throwArg argument converter

Throws an error if a argument if truthy.

var potem = require('potem').potem;

var func = function (callback) {
  callback(new Error('an error'), 'success');
}

var p = potem()
  .then(function () {
    func(p.pause(1, p.throwArg);
  })
  .then(function (message) {
    //this function is never called
  })
  .error(function (err) {
    //err is thrown. err.message === 'an error'
  });

This argument converter is especially useful when working with nodejs.

var p = potem()
  .then(function () {
    fs.writeFile('tmp.tmp', 'a', p.pause(1, p.throwArg));
    fs.writeFile('tmp2.tmp', 'b', p.pause(1, p.throwArg));
  })
  .then([function (write1, write2) {
    fs.readFile('tmp.tmp', p.pause(1, p.throwArg));
    fs.readFile('tmp2.tmp', p.pause(1, p.throwArg));
  }])
  .then([function (read1, read2) {
    return read1 + read2;
  }])
  .then(function (concatenation) {
    expect(concatenation === 'ab' || concatenation === 'ba').toBeTruthy();
  })
  .error(function (e) {
    console.log('e', e);
    next(e);
  })
  .fin(function () {
    fs.unlink('tmp.tmp', p.pause());
    fs.unlink('tmp2.tmp', p.pause());
  })
  .then(next);

In nodejs it is very common that we have this callback signature:

interface INodejsCallback {
    (err:Error, arg:any):void;
}

So we usually would use pause like this: p.pause(1, p.throwArg). For this reason there is a helper method added: p.stdPause() that is equivalent with p.pause(1, p.throwArg).

Plans for a next version???

Warning not implemented yet!

Here is a draft of what is comming to be a part of v4.0:

var files = [];
var seq = potem();
seq(() => fs.readdir('./', seq.pause(1, throwArg));
seq.each((dirItem, index) => {
    var i = potem();
    i(() => fs.stat('./' + dirItem, i.pause(1, i.throwArg)));
    i.if((stat) => stat.isFile, (stat) => fs.readFile(stat.path, i.pause(1, i.throwArg)));
    i((fileContent) => {
        files.push(fileContent);
    });
    i.finally(seq.pause(1, seq.throwArg));
});

potem's People

Contributors

finalclass avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.