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(loop, *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.



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/libuv/q.rb', line 359

def all(loop, *promises)
    deferred = Q.defer(loop)
    counter = promises.length
    results = []
    
    if counter > 0
        promises.each_index do |index|
            ref(loop, 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(@loop, reason)    # Don't modify result
            })
        end
    else
        deferred.resolve(results)
    end
    
    return deferred.promise
end

.any(loop, *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



394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/libuv/q.rb', line 394

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

.defer(loop) ⇒ Deferred

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

Returns:

  • (Deferred)

    Returns a new instance of Deferred



308
309
310
# File 'lib/libuv/q.rb', line 308

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

.finally(loop, *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.



419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/libuv/q.rb', line 419

def self.finally(loop, *promises)
    deferred = Q.defer(loop)
    counter = promises.length
    results = []
    
    if counter > 0
        promises.each_index do |index|
            ref(loop, promises[index]).then(proc {|result|
                if results[index].nil?
                    results[index] = [result, false]
                    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(@loop, reason)    # Don't modify result
            })
        end
    else
        deferred.resolve(results)
    end
    
    return deferred.promise
end

.reject(loop, 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(loop, 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



346
347
348
# File 'lib/libuv/q.rb', line 346

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