Class: Whenner::Deferred

Inherits:
Object
  • Object
show all
Defined in:
lib/whenner/deferred.rb

Overview

A deferred object is an operation that will eventually resolve to a result value. A deferred can be in three possible states:

  • Pending: it has been created but not yet resolved.
  • Fulfilled: it has been successfully resolved.
  • Rejected: it has been unsuccessfully resolved.

A deferred might transition from pending to fulfilled or rejected, but it will not transition again once resolved (resolved can be either fulfilled or rejected).

When a deferred does resolve, it will trigger any applicable callbacks. You can stack on callbacks on a deferred object before it has been resolved and they will be called later. When you register callbacks on an already resolved deferred, the callback will be called immediately. Note that a callback will only be run once.

When a callback is in the fulfilled state, it has a value that represents its eventual outcome. When it is rejected, it has a reason.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDeferred

Returns a new instance of Deferred.



25
26
27
28
29
30
31
# File 'lib/whenner/deferred.rb', line 25

def initialize
  @promise             = Promise.new(self)
  @state               = :pending
  @fulfilled_callbacks = []
  @rejected_callbacks  = []
  @always_callbacks    = []
end

Instance Attribute Details

#promisePromise (readonly)

Returns a promise for this deferred.

Returns:

  • (Promise)

    a promise for this deferred



23
24
25
# File 'lib/whenner/deferred.rb', line 23

def promise
  @promise
end

#reasonObject

The reason the deferred was rejected.

Raises:



44
45
46
47
# File 'lib/whenner/deferred.rb', line 44

def reason
  raise UnresolvedError unless resolved?
  @reason
end

#valueObject

The value the deferred was resolved with.

Raises:



36
37
38
39
# File 'lib/whenner/deferred.rb', line 36

def value
  raise UnresolvedError unless resolved?
  @value
end

Instance Method Details

#always {|value, reason| ... } ⇒ Promise

Register a callback to be run when the deferred is resolved.

Yield Parameters:

  • value (Object)
  • reason (Object)

Returns:

  • (Promise)

    a new promise representing the return value of the callback, or -- when that return value is a promise itself -- a promise mimicking that promise.



141
142
143
144
145
146
# File 'lib/whenner/deferred.rb', line 141

def always(&block)
  cb = Callback.new(block)
  always_callbacks << cb
  cb.call(*callback_response) if resolved?
  cb.promise
end

#done {|value| ... } ⇒ Promise

Register a callback to be run when the deferred is fulfilled.

Yield Parameters:

  • value (Object)

Returns:

  • (Promise)

    a new promise representing the return value of the callback, or -- when that return value is a promise itself -- a promise mimicking that promise.



114
115
116
117
118
119
# File 'lib/whenner/deferred.rb', line 114

def done(&block)
  cb = Callback.new(block)
  fulfilled_callbacks << cb
  cb.call(*callback_response) if fulfilled?
  cb.promise
end

#fail {|reason| ... } ⇒ Promise

Register a callback to be run when the deferred is rejected.

Yield Parameters:

  • reason (Object)

Returns:

  • (Promise)

    a new promise representing the return value of the callback, or -- when that return value is a promise itself -- a promise mimicking that promise.



127
128
129
130
131
132
# File 'lib/whenner/deferred.rb', line 127

def fail(&block)
  cb = Callback.new(block)
  rejected_callbacks << cb
  cb.call(*callback_response) if rejected?
  cb.promise
end

#fulfill(value = nil) ⇒ Deferred

Fulfill this promise with an optional value. The value will be stored in the deferred and passed along to any registered done callbacks.

When fulfilling a deferred twice, nothing happens.

Returns:

Raises:



76
77
78
79
80
81
82
83
84
# File 'lib/whenner/deferred.rb', line 76

def fulfill(value = nil)
  raise CannotTransitionError if rejected?
  return if fulfilled?
  unless resolved?
    self.value = value
    resolve_to(:fulfilled)
  end
  self
end

#fulfilled?Boolean

Returns whether the deferred was successfully resolved.

Returns:

  • (Boolean)

    whether the deferred was successfully resolved.



55
56
57
# File 'lib/whenner/deferred.rb', line 55

def fulfilled?
  state == :fulfilled
end

#pending?Boolean

Returns whether the deferred has not been resolved yet.

Returns:

  • (Boolean)

    whether the deferred has not been resolved yet.



50
51
52
# File 'lib/whenner/deferred.rb', line 50

def pending?
  state == :pending
end

#reject(reason = nil) ⇒ Deferred

Reject this promise with an optional reason. The reason will be stored in the deferred and passed along to any registered fail callbacks.

When rejecting a deferred twice, nothing happens.

Returns:

Raises:



93
94
95
96
97
98
99
100
101
# File 'lib/whenner/deferred.rb', line 93

def reject(reason = nil)
  raise CannotTransitionError if fulfilled?
  return if rejected?
  unless resolved?
    self.reason = reason
    resolve_to(:rejected)
  end
  self
end

#rejected?Boolean

Returns whether the deferred was rejected.

Returns:

  • (Boolean)

    whether the deferred was rejected.



60
61
62
# File 'lib/whenner/deferred.rb', line 60

def rejected?
  state == :rejected
end

#resolved?Boolean

Returns whether the deferred was either fulfilled or rejected.

Returns:

  • (Boolean)

    whether the deferred was either fulfilled or rejected.



65
66
67
# File 'lib/whenner/deferred.rb', line 65

def resolved?
  fulfilled? || rejected?
end

#to_promisePromise

Returns:



104
105
106
# File 'lib/whenner/deferred.rb', line 104

def to_promise
  promise
end