Module: Libuv::Q

Included in:
Deferred
Defined in:
lib/libuv/q.rb

Defined Under Namespace

Classes: Deferred, DeferredPromise, Promise, ResolvedPromise

Class Method Summary collapse

Class Method Details

.all(reactor, *promises) ⇒ Promise

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.

Parameters:

  • Promises (*Promise)

    a number of promises that will be combined into a single promise

Returns:

  • (Promise)

    Returns a single promise that will be resolved with an array of values, each value corresponding to the promise at the same index in the ‘promises` array. If any of the promises is resolved with a rejection, this resulting promise will be resolved with the same rejection.



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/libuv/q.rb', line 372

def all(reactor, *promises)
    deferred = Q.defer(reactor)
    promises = promises.flatten
    counter = promises.length
    results = []

    if counter > 0
        promises.each_index do |index|
            ref(reactor, promises[index]).then(proc {|result|
                if results[index].nil?
                    results[index] = result
                    counter -= 1
                    deferred.resolve(results) if counter <= 0
                end
                result
            }, proc {|reason|
                if results[index].nil?
                    deferred.reject(reason)
                end
                Q.reject(@reactor, reason)    # Don't modify result
            })
        end
    else
        deferred.resolve(results)
    end

    return deferred.promise
end

.any(reactor, *promises) ⇒ Promise

Combines multiple promises into a single promise that is resolved when any of the input promises are resolved.

Parameters:

  • Promises (*Promise)

    a number of promises that will be combined into a single promise

Returns:

  • (Promise)

    Returns a single promise



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/libuv/q.rb', line 408

def any(reactor, *promises)
    deferred = Q.defer(reactor)
    promises = promises.flatten
    if promises.length > 0
        promises.each_index do |index|
            ref(reactor, promises[index]).then(proc {|result|
                deferred.resolve(true)
                result
            }, proc {|reason|
                deferred.reject(false)
                Q.reject(@reactor, reason)    # Don't modify result
            })
        end
    else
        deferred.resolve(true)
    end
end

.defer(reactor) ⇒ Deferred

Creates a Deferred object which represents a task which will finish in the future.

Returns:

  • (Deferred)

    Returns a new instance of Deferred



321
322
323
# File 'lib/libuv/q.rb', line 321

def defer(reactor)
    return Deferred.new(reactor)
end

.finally(reactor, *promises) ⇒ Promise

Combines multiple promises into a single promise that is resolved when all of the input promises are resolved or rejected.

Parameters:

  • Promises (*Promise)

    a number of promises that will be combined into a single promise

Returns:

  • (Promise)

    Returns a single promise that will be resolved with an array of values, each [result, wasResolved] value pair corresponding to a at the same index in the ‘promises` array.



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/libuv/q.rb', line 434

def self.finally(reactor, *promises)
    deferred = Q.defer(reactor)
    promises = promises.flatten
    counter = promises.length
    results = []

    if counter > 0
        promises.each_index do |index|
            ref(reactor, promises[index]).then(proc {|result|
                if results[index].nil?
                    results[index] = [result, true]
                    counter -= 1
                    deferred.resolve(results) if counter <= 0
                end
                result
            }, proc {|reason|
                if results[index].nil?
                    results[index] = [reason, false]
                    counter -= 1
                    deferred.resolve(results) if counter <= 0
                end
                Q.reject(@reactor, reason)    # Don't modify result
            })
        end
    else
        deferred.resolve(results)
    end

    return deferred.promise
end

.reject(reactor, reason = nil) ⇒ Promise

Creates a promise that is resolved as rejected with the specified reason. This api should be used to forward rejection in a chain of promises. If you are dealing with the last promise in a promise chain, you don’t need to worry about it.

When comparing deferreds/promises to the familiar behaviour of try/catch/throw, think of reject as the raise keyword in Ruby. This also means that if you “catch” an error via a promise error callback and you want to forward the error to the promise derived from the current promise, you have to “rethrow” the error by returning a rejection constructed via reject.

Examples:

handling rejections

#!/usr/bin/env ruby

require 'rubygems' # or use Bundler.setup
require 'em-promise'

promiseB = promiseA.then(lambda {|reason|
  # error: handle the error if possible and resolve promiseB with newPromiseOrValue,
  #        otherwise forward the rejection to promiseB
  if canHandle(reason)
    # handle the error and recover
    return newPromiseOrValue
  end
  return Q.reject(reactor, reason)
}, lambda {|result|
  # success: do something and resolve promiseB with the old or a new result
  return result
})

Parameters:

  • reason (Object) (defaults to: nil)

    constant, message, exception or an object representing the rejection reason.

Returns:

  • (Promise)

    Returns a promise that was already resolved as rejected with the reason



359
360
361
# File 'lib/libuv/q.rb', line 359

def reject(reactor, reason = nil)
    return ResolvedPromise.new(reactor, reason, true)    # A resolved failed promise
end