H
H
HoHsi2015-12-08 22:16:12
JavaScript
HoHsi, 2015-12-08 22:16:12

Which Node.js Promise Library to Use?

Good evening!
Which Node.js promise library to use (what is their difference? Why are there so many of them, even for the JS world?):
* promise
* q
* rsvp
* when
* mpromise
* Over 9000
D:

Answer the question

In order to leave comments, you need to log in

4 answer(s)
H
HoHsi, 2015-12-09
@HoHsi

Wrote a performance test.

# Requires
Benchmark   = require 'benchmark'
lagoon      = require 'lagoonjs'

async       = require 'async'
Q           = require 'q'
bluebird    = require 'bluebird'
RSVP        = require 'rsvp'
whenpromise = require 'when'
# mpromise    = require 'mpromise' # Не соответствует стандарту
es6         = require 'es6-promise'
kew         = require 'kew'

# Init
logger      = new lagoon.Lagoon()

# Functions
fakeDelay = (name)-> (delay = 3)-> (callback)=>
    # console.log "[#{ name }] +"
    setTimeout =>
        callback()
    , delay

fakeDelayPromiseQ = (delay)->
    deferred = Q.defer()

    fakeDelay("q")(delay) =>
        deferred.resolve()

    return deferred.promise

fakeDelayPromiseBB = (delay)->
    new bluebird (resolve, reject)->
        fakeDelay("Bluebird")(delay) =>
            resolve()

fakeDelayPromiseRSVP = (delay)->
    new RSVP.Promise (resolve, reject)->
        fakeDelay("RSVP")(delay) =>
            resolve()

fakeDelayPromiseWhen = (delay)->
    deferred = whenpromise.defer()

    fakeDelay("When")(delay) =>
        deferred.resolve()

    return deferred.promise

# fakeDelayPromiseM = (delay)->
#     new mpromise (resolve, reject)->
#         fakeDelay("M")(delay) =>
#             resolve()

fakeDelayPromiseES6 = (delay)->
    new es6.Promise (resolve, reject)->
        fakeDelay("ES6")(delay) =>
            resolve()

fakeDelayPromiseKew = (delay)->
    deferred = kew.defer()

    fakeDelay("Kew")(delay) =>
        deferred.resolve()

    return deferred.promise

# Time
BenchmarkAsync = (delay, times = 3)-> new Benchmark "Async#parallel X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelay("Async")(delay)

        async.parallel queue, =>
            deferred.resolve()
}

BenchmarkQ = (delay, times = 3)-> new Benchmark "Q#all X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseQ(delay)

        Q.all(queue).then =>
            deferred.resolve()
}

BenchmarkBluebird = (delay, times = 3)-> new Benchmark "Bluebird#all X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseBB(delay)

        bluebird.all(queue).then =>
            deferred.resolve()
}

BenchmarkRSVP = (delay, times = 3)-> new Benchmark "RSVP#all X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseRSVP(delay)

        RSVP.all(queue).then =>
            deferred.resolve()
}

BenchmarkWhen = (delay, times = 3)-> new Benchmark "When#all X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseWhen(delay)

        whenpromise.all(queue).then =>
            deferred.resolve()
}

# BenchmarkM = (delay, times = 3)-> new Benchmark "M#all X #{ times } [#{ delay }ms]", {
#     defer: true
#     fn: (deferred)->
#         queue = []
#         for [0...times]
#             queue.push fakeDelayPromiseM(delay)

#         mpromise.all(queue).then =>
#             deferred.resolve()
# }

BenchmarkES6 = (delay, times = 3)-> new Benchmark "ES6#all X #{ times } [#{ delay }ms]", {
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseES6(delay)

        es6.Promise.all(queue).then =>
            deferred.resolve()
}

BenchmarkKew = (delay, times = 3)-> new Benchmark "Kew#all X #{ times } [#{ delay }ms]", { 
    defer: true
    fn: (deferred)->
        queue = []
        for [0...times]
            queue.push fakeDelayPromiseKew(delay)

        kew.all(queue).then =>
            deferred.resolve()
}

results = {}
async.eachLimit [1, 3, 100, 300, 1000, 5000, 10000, 50000, 100000, 1000000], 1, (times, cbt)->
    async.eachLimit [1, 5, 300, 1000], 1, (delay, cbd)->
        suite = new Benchmark.Suite

        suite.add BenchmarkAsync( delay, times )
             .add BenchmarkQ( delay, times )
             .add BenchmarkBluebird( delay, times )
             .add BenchmarkRSVP( delay, times )
             .add BenchmarkWhen( delay, times )
             .add BenchmarkES6( delay, times )
             .add BenchmarkKew( delay, times )
             .on 'cycle', (event)->
                 logger.info String(event.target)
             .on 'complete', ->
                 logger.warn "Fastest is #{ @.filter('fastest').pluck('name') }"
                 results[ times ] ?= {}
                 results[ times ][ delay ] = @.filter('fastest').pluck('name')

                 cbd()
             .run { 
                 'initCount': 100
                 'async': false
                 'defer': true
             }
    , ->
        cbt()
, ->
    logger.log ''
    logger.log ''
    logger.log ''
    for times, resultd of results
        logger.log ''
        for delay, result of resultd
            logger.warn "Fastest is #{ result }"

S
Sergey, 2015-12-08
Protko @Fesor

https://github.com/jakearchibald/es6-promise

D
Dmitry Belyaev, 2015-12-08
@bingo347

All promise libraries are implementations for es5
in the node, and even under the browser, you can already safely write on es6 where promises are native
ps my choice often still stops at the bluebird library as an extended implementation

D
Dmitry Vapelnik, 2015-12-09
@dvapelnik

I settled on bluebird - there are a lot of different little birds

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question