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.



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/libuv/q.rb', line 350

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



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/libuv/q.rb', line 385

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



299
300
301
# File 'lib/libuv/q.rb', line 299

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.



410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/libuv/q.rb', line 410

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



337
338
339
# File 'lib/libuv/q.rb', line 337

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