diff --git a/lib/promise.rb b/lib/promise.rb index 9594cef..a052653 100644 --- a/lib/promise.rb +++ b/lib/promise.rb @@ -51,7 +51,7 @@ def then(on_fulfill = nil, on_reject = nil, &block) on_fulfill ||= block next_promise = self.class.new - add_callback(Callback.new(self, on_fulfill, on_reject, next_promise)) + add_callback(Callback.new(on_fulfill, on_reject, next_promise)) next_promise end @@ -68,7 +68,7 @@ def sync def fulfill(value = nil) if Promise === value - Callback.assume_state(value, self) + value.add_callback(self) else dispatch do @state = :fulfilled @@ -89,6 +89,16 @@ def defer yield end + protected + + def add_callback(callback) + if pending? + @callbacks << callback + else + dispatch!(callback) + end + end + private def reason_coercion(reason) @@ -101,14 +111,6 @@ def reason_coercion(reason) reason end - def add_callback(callback) - if pending? - @callbacks << callback - else - dispatch!(callback) - end - end - def dispatch if pending? yield @@ -118,6 +120,12 @@ def dispatch end def dispatch!(callback) - defer { callback.call } + defer do + if fulfilled? + callback.fulfill(value) + else + callback.reject(reason) + end + end end end diff --git a/lib/promise/callback.rb b/lib/promise/callback.rb index 4c112f4..fc7df19 100644 --- a/lib/promise/callback.rb +++ b/lib/promise/callback.rb @@ -2,38 +2,35 @@ class Promise class Callback - def self.assume_state(source, target) - on_fulfill = target.public_method(:fulfill) - on_reject = target.public_method(:reject) - source.then(on_fulfill, on_reject) - end - - def initialize(promise, on_fulfill, on_reject, next_promise) - @promise = promise + def initialize(on_fulfill, on_reject, next_promise) @on_fulfill = on_fulfill @on_reject = on_reject @next_promise = next_promise end - def call - if @promise.fulfilled? - call_block(@on_fulfill, @promise.value) + def fulfill(value) + if @on_fulfill + call_block(@on_fulfill, value) else - call_block(@on_reject, @promise.reason) + @next_promise.fulfill(value) end end - def call_block(block, param) - if block - begin - @next_promise.fulfill(block.call(param)) - rescue => ex - @next_promise.reject(ex) - end + def reject(reason) + if @on_reject + call_block(@on_reject, reason) else - self.class.assume_state(@promise, @next_promise) + @next_promise.reject(reason) end end + + private + + def call_block(block, param) + @next_promise.fulfill(block.call(param)) + rescue => ex + @next_promise.reject(ex) + end end private_constant :Callback end