GithubHelp home page GithubHelp logo

dfilatov / vow Goto Github PK

View Code? Open in Web Editor NEW
344.0 344.0 46.0 675 KB

ES6-compatible and Promises/A+ implementation for Node.js and browsers

License: MIT License

Makefile 0.17% JavaScript 99.33% Shell 0.50%

vow's Introduction

Vow NPM Version Build Status NPM Downloads

Vow is a Promises/A+ implementation. It also supports ES6 Promises specification.

Full API reference can be found at http://dfilatov.github.io/vow/.

Getting Started

In Node.js

You can install using Node Package Manager (npm):

npm install vow

In Browsers

<script type="text/javascript" src="vow.min.js"></script>

It also supports RequireJS module format and YM module format.

Vow has been tested in IE6+, Mozilla Firefox 3+, Chrome 5+, Safari 5+, Opera 10+.

Usage

Creating a promise

There are two possible ways to create a promise.

1. Using a deferred

function doSomethingAsync() {
    var deferred = vow.defer();
    
    // now you can resolve, reject, notify corresponging promise within `deferred`
    // e.g. `defer.resolve('ok');`
        
    return deferred.promise(); // and return corresponding promise to subscribe to reactions
}

doSomethingAsync().then(
    function() {}, // onFulfilled reaction
    function() {}, // onRejected reaction
    function() {}  // onNotified reaction
    );

The difference between deferred and promise is that deferred contains methods to resolve, reject and notify corresponding promise, but the promise by itself allows only to subscribe on these actions.

2. ES6-compatible way

function doSomethingAsync() {
    return new vow.Promise(function(resolve, reject, notify) {
        // now you can resolve, reject, notify the promise
    });
}

doSomethingAsync().then(
    function() {}, // onFulfilled reaction
    function() {}, // onRejected reaction
    function() {}  // onNotified reaction
    );

Extensions and related projects

  • vow-fs — vow-based file I/O for Node.js
  • vow-node — extension for vow to work with nodejs-style callbacks
  • vow-queue — vow-based task queue with weights and priorities
  • vow-asker — wraps asker API in the vow promises implementation

NOTE. Documentation for old versions of the library can be found at https://github.com/dfilatov/vow/blob/0.3.x/README.md.

vow's People

Contributors

alexeyten avatar dfilatov avatar dimik avatar dodev avatar golyshevd avatar i-akhmadullin avatar ikokostya avatar lvivski avatar marcodejongh avatar markelog avatar mdevils avatar thekashey avatar tworoger avatar vs-kurkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vow's Issues

Feature request: Mux

I often encounter situations where I have to call an async function multiple times:

friends.forEach(function(friend) {
    friend.save(callback);
});

It want to block on a call to all these. Sure, I could use async framework. Sometimes that is clunky, so I wrote Mux:

var myMux = new Vow.Mux();
friends.forEach(function(friend) {
    friend.save(myMux.createCallback());
});
myMux.then(function() {
    done();
});

Here is the library code and unit test.

// extend vow with helpers
var Vow = require('vow');

var Mux = module.exports = function Mux() {
    /**
     * An array of callbacks this Mux wraps
     * @type {Array}
     * @private
     */
    this._callbacks = [];

    /**
     * The results from all successful callbacks
     * @type {Array}
     * @private
     */
    this._results = [];

    /**
     * The error from all error callbacks
     * @type {Array}
     * @private
     */
    this._errors = [];

    /**
     * Count the number of times the callback wrapper is invoked
     * @type {number}
     * @private
     */
    this._countCallsBack = 0;

    /**
     * @type {Promise}
     * @private
     */
    this._innerPromise = Vow.promise();

    // copy Vow prototype over Mux
    for (var x in this._innerPromise) this[x] = this._innerPromise[x];
};

/**
 * Handles callbacks made to function created in createCallback
 * @param {number} position
 * @param {Error|null} err
 * @param {*} result
 * @private
 */
Mux.prototype._onCallback = function(position, err, result) {
    ++this._countCallsBack;

    // save error
    if (typeof err === 'undefined') {
        this._errors[position] = null;
    } else {
        this._errors[position] = err;
    }

    // save result
    if (typeof result === 'undefined') {
        this._results[position] = null;
    } else {
        this._results[position] = result;
    }

    if (this.isResolved()) {
        // already resolved
        return;
    } else if (err) {
        // reject on first error
        this.reject(err);
    } else if (this._countCallsBack === this._callbacks.length) {
        // fulfill with all available results
        this.fulfill(this._results);
    }
};

/**
 * Create one or more callbacks backed by a single promise
 * @returns {Function}
 */
Mux.prototype.createCallback = function() {
    var callback = this._onCallback.bind(this, this._callbacks.length);
    this._callbacks.push(callback);
    return callback;
}

Unit tests:

var assert = require('assert');
var Vow = require('../lib/vow');

describe('Vow.Mux', function() {
    it('resolve naive', function(done) {
        var m = new Vow.Mux();
        m.then(function() {
            done();
        }, function() {
            assert.fail('should not be rejected');
        });
        m.fulfill();
    });

    it('all callbacks', function(done) {
        var m = new Vow.Mux();
        m.then(function() {
            assert.equal(m._countCallsBack, 100);
            done();
        }, function() {
            assert.fail('should not be rejected');
        });

        var callbacks = [];
        for (var i = 0; i < 100; ++i) {
            setTimeout(m.createCallback(), i);
        }
    });

    it('reject on first', function(done) {
        var m = new Vow.Mux();
        m.then(function() {
            assert.fail('should not be fulfilled');
        }, function(err) {
            assert.equal(err.message, 'there is no spoon');
            done();
        });

        var callbacks = [];
        for (var i = 0; i < 100; ++i) {
            if (i === 69) {
                // 69 is an error
                setTimeout(m.createCallback().bind(m, new Error('there is no spoon')), i);
            } else if (i > 69) {
                // other error
                setTimeout(m.createCallback().bind(m, new Error('foobar')), i);
            } else {
                setTimeout(m.createCallback(), i);
            }
        }
    });
});

How to run tests in the browser?

You claim for browser support. But how to run tests inside the browser? Consider Mocha + Chai for tests. They support browser and NodeJS.

Нотификация

Я тут попробовал использовать нотификацию (defer.notify + promise.progress) и получил миллион вызовов обработчика progress, среди них есть те что должны были произойти, однако 99% вызывается просто без параметров.

Я полез в твой код и вижу это
https://github.com/dfilatov/vow/blob/master/lib/vow.js#L564

Если я меняю defer.notify(res); на void(0); все начинает работать корректно.
Кажется это баг.

Pass progress state from items in all array/objects methods

Хочется чтобы методы типа all и allResolved подписывались не только на reject и resolve, но и на нотификацию каждого промиса в коллекции.
Чтобы сейчас получить эти нотификации приходится их самому перебирать и подписываться, а также создавать новый defer, и возвращать его промис вместо результата all и allResolved. Это очень неудобно.

Use native Promise if possible

According to release notes, Chrome 35 Beta supports DOM promises by default (they are already available in Canary as well).

Haven't you thought about adding support of native Promise object to vow, if it's available in browser?

module.exports fires before modules.define

Было бы правильнее, в коде библиотеки, сначала проверять доступность modules и define и только после делать module.exports.

Сейчас если использовать vow из Node.js всегда будет срабатывать exports, даже если я хочу использовать модули.

construct to only call fail on vow.all when: all are resolved and any are rejected?

It there a way, with vow.all or otherwise, to call fail only when all promises are resolved and any are rejected?
usecase: aggregating errors.

See the following construct how I'd like it to be:

vow.all([promise1,promise2])
.then(function(){
//only fired when all resolved and all fulfilled
}).fail(function(err){
//only fired when all resolved and any failed
//currently with vow.all: any resolved and any failed
});

Is there a way to do this?

Buggy behavior if fail called before then on promise

var promise = require('vow').promise();

function done (from, obj) {
    console.log(from, obj);
}

promise
    .fail(function (a) {
        done('FAIL', a);
    })
    .then(function (a) {
        done('THEN', a);
    });

promise.reject('zxc');q

Actual output:

FAIL zxc
THEN undefined

Expected:

FAIL zxc

Use setImmediate instead of process.nextTick with latest node versions

Hi!
I had an issue with some recursive calls of third party lib.
The log message looks like this:

(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
RangeError: Maximum call stack size exceeded

When i have changed nextTick with setImmediate in your Vow code,
it starts fail silently =)

Vow doesn't properly work in mocha/phantomjs environment

Vow's nextTick function relies on "process" global variable as a sign of nodeJs.

But in phantomjs/mocha environment has global var "process" that doesn't have nextTick.

It would be better to update it with a more reliable check of environment / or at least check for existence of nextTick property.

Exceptions don't contain full stack trace

When exception happens it looks like this:
/Users/scf/Projects/bem-tools/node_modules/vow/lib/vow.js:413
throw e;
^
Error: ENOENT, open '/Users/scf/Projects/bem-tools/test-make-temp/pages/example/example.bemdecl1.js'

There is no trace of the user code cause it to raise.

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.