lib/em-promise/defer.rb in em-promise-1.0.1 vs lib/em-promise/defer.rb in em-promise-1.0.2
- old
+ new
@@ -22,24 +22,20 @@
wrappedCallback = proc { |value|
begin
result.resolve(callback.nil? ? value : callback.call(value))
rescue => e
- #
- # TODO:: add debugging output here
- #
+ warn "\nUnhandled exception: #{e.message}\n#{e.backtrace.join("\n")}\n"
result.reject(e);
end
}
wrappedErrback = proc { |reason|
begin
result.resolve(errback.nil? ? Defer.reject(reason) : errback.call(reason))
rescue => e
- #
- # TODO:: add debugging output here
- #
+ warn "Unhandled exception: #{e.message}\n#{e.backtrace.join("\n")}\n"
result.reject(e);
end
}
#
@@ -73,10 +69,11 @@
end
class ResolvedPromise < Promise
def initialize(response, error = false)
+ raise ArgumentError if error && response.is_a?(Promise)
@error = error
@response = response
end
def then(callback = nil, errback = nil, &blk)
@@ -109,15 +106,13 @@
callbacks = @pending
@pending = nil
@value = ref(val)
if callbacks.length > 0
- EM.next_tick {
- callbacks.each do |callback|
- @value.then(callback[0], callback[1])
- end
- }
+ callbacks.each do |callback|
+ @value.then(callback[0], callback[1])
+ end
end
end
end
end
@@ -166,16 +161,57 @@
# @param [Object] reason constant, message, exception or an object representing the rejection reason.
def self.reject(reason = nil)
return ResolvedPromise.new( reason, true ) # A resolved failed promise
end
+ #
+ # Combines multiple promises into a single promise that is resolved when all of the input
+ # promises are resolved.
+ #
+ # @param [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.
+ def self.all(*promises)
+ deferred = Defer.new
+ counter = promises.length
+ results = []
+
+ if counter > 0
+ promises.each_index do |index|
+ ref(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
+ reason
+ })
+ end
+ else
+ deferred.resolve(results)
+ end
+
+ return deferred.promise
+ end
+
protected
- def ref(value)
+ def self.ref(value)
return value if value.is_a?(Promise)
return ResolvedPromise.new( value ) # A resolved success promise
+ end
+
+ def ref(value)
+ Defer.ref(value)
end
end
end