em_promise.rb

 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 wait
24		fiber = Fiber.current
25		resume = proc do |arg|
26			defer { fiber.resume(arg) }
27		end
28
29		self.then(resume, resume)
30		Fiber.yield
31	end
32
33	def self.reject(e)
34		new.tap { |promise| promise.reject(e) }
35	end
36end
37
38module EventMachine
39	module Deferrable
40		def promise
41			EMPromise.new(self)
42		end
43
44		[:then, :rescue, :catch].each do |method|
45			define_method(method) do |*args, &block|
46				promise.public_send(method, *args, &block)
47			end
48		end
49	end
50end