1require "eventmachine"
 2require "promise"
 3
 4class EMPromise < Promise
 5	def initialize(deferrable=nil)
 6		super()
 7		fulfill(deferrable) if deferrable
 8	end
 9
10	def fulfill(value, bind_defer=true)
11		if bind_defer && value.is_a?(EM::Deferrable)
12			value.callback { |x| fulfill(x, false) }
13			value.errback(&method(:reject))
14		else
15			super(value)
16		end
17	end
18
19	def defer
20		EM.next_tick { yield }
21	end
22
23	def self.reject(e)
24		new.tap { |promise| promise.reject(e) }
25	end
26end
27
28module EventMachine
29	module Deferrable
30		def promise
31			EMPromise.new(self)
32		end
33
34		[:then, :rescue, :catch].each do |method|
35			define_method(method) do |*args, &block|
36				promise.public_send(method, *args, &block)
37			end
38		end
39	end
40end