Skip to content

Commit

Permalink
Remove Array object allocation for promises with 0 or 1 callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanahsmith committed Jun 13, 2017
1 parent 1090b8e commit 2f5d63b
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions lib/promise.rb
Expand Up @@ -38,7 +38,7 @@ def self.sync(obj)

def initialize
@state = :pending
@callbacks = []
@callbacks = nil
end

def pending?
Expand Down Expand Up @@ -116,7 +116,7 @@ def defer

def add_callback(callback)
if pending?
@callbacks << callback
@callbacks = lazy_array_append(@callbacks, callback)
callback.source = self
else
dispatch!(callback)
Expand All @@ -125,6 +125,24 @@ def add_callback(callback)

private

def lazy_array_append(lazy_array, new_item)
if lazy_array.instance_of?(Array)
lazy_array << new_item
elsif lazy_array
[lazy_array, new_item]
else
new_item
end
end

def lazy_array_each(lazy_array)
if lazy_array.instance_of?(Array)
lazy_array.each { |item| yield item }
elsif lazy_array
yield lazy_array
end
end

def reason_coercion(reason)
case reason
when Exception
Expand All @@ -138,7 +156,7 @@ def reason_coercion(reason)
def dispatch
if pending?
yield
@callbacks.each { |callback| dispatch!(callback) }
lazy_array_each(@callbacks) { |callback| dispatch!(callback) }
nil
end
end
Expand Down

0 comments on commit 2f5d63b

Please sign in to comment.