Class: Promise

Inherits:
Object
  • Object
show all
Includes:
Observer, Progress
Defined in:
lib/promise.rb,
lib/promise/group.rb,
lib/promise/version.rb,
lib/promise/observer.rb,
lib/promise/progress.rb

Defined Under Namespace

Modules: Observer, Progress

Constant Summary collapse

Error =
Class.new(RuntimeError)
BrokenError =
Class.new(Error)
VERSION =
'0.7.4'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Progress

#on_progress, #progress

Constructor Details

#initializePromise

Returns a new instance of Promise.



40
41
42
# File 'lib/promise.rb', line 40

def initialize
  @state = :pending
end

Instance Attribute Details

#reasonObject (readonly)

Returns the value of attribute reason.



17
18
19
# File 'lib/promise.rb', line 17

def reason
  @reason
end

#sourceObject

Returns the value of attribute source.



16
17
18
# File 'lib/promise.rb', line 16

def source
  @source
end

#stateObject (readonly)

Returns the value of attribute state.



17
18
19
# File 'lib/promise.rb', line 17

def state
  @state
end

#valueObject (readonly)

Returns the value of attribute value.



17
18
19
# File 'lib/promise.rb', line 17

def value
  @value
end

Class Method Details

.all(enumerable) ⇒ Object



24
25
26
# File 'lib/promise.rb', line 24

def self.all(enumerable)
  Group.new(new, enumerable).promise
end

.map_value(obj) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/promise.rb', line 28

def self.map_value(obj)
  if obj.is_a?(Promise)
    obj.then { |value| yield value }
  else
    yield obj
  end
end

.resolve(obj = nil) ⇒ Object



19
20
21
22
# File 'lib/promise.rb', line 19

def self.resolve(obj = nil)
  return obj if obj.is_a?(self)
  new.tap { |promise| promise.fulfill(obj) }
end

.sync(obj) ⇒ Object



36
37
38
# File 'lib/promise.rb', line 36

def self.sync(obj)
  obj.is_a?(Promise) ? obj.sync : obj
end

Instance Method Details

#fulfill(value = nil) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/promise.rb', line 87

def fulfill(value = nil)
  return self unless pending?

  if value.is_a?(Promise)
    case value.state
    when :fulfilled
      fulfill(value.value)
    when :rejected
      reject(value.reason)
    else
      @source = value
      value.subscribe(self, nil, nil)
    end
  else
    @source = nil

    @state = :fulfilled
    @value = value

    notify_fulfillment if defined?(@observers)
  end

  self
end

#fulfilled?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/promise.rb', line 48

def fulfilled?
  state.equal?(:fulfilled)
end

#pending?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/promise.rb', line 44

def pending?
  state.equal?(:pending)
end

#reject(reason = nil) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/promise.rb', line 112

def reject(reason = nil)
  return self unless pending?

  @source = nil
  @state = :rejected
  @reason = reason_coercion(reason || Error)

  notify_rejection if defined?(@observers)

  self
end

#rejected?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/promise.rb', line 52

def rejected?
  state.equal?(:rejected)
end

#rescue(&block) ⇒ Object Also known as: catch



73
74
75
# File 'lib/promise.rb', line 73

def rescue(&block)
  self.then(nil, block)
end

#subscribe(observer, on_fulfill_arg, on_reject_arg) ⇒ Object

Subscribe the given ‘observer` for status changes of a `Promise`.

The observer will be notified about state changes of the promise by calls to its ‘#promise_fulfilled` or `#promise_rejected` methods.

These methods will be called with two arguments, the first being the observed ‘Promise`, the second being the `on_fulfill_arg` or `on_reject_arg` given to `#subscribe`.

Parameters:

Raises:



146
147
148
149
150
151
152
153
154
155
# File 'lib/promise.rb', line 146

def subscribe(observer, on_fulfill_arg, on_reject_arg)
  raise Error, 'Non-pending promises can not be observed' unless pending?

  unless observer.is_a?(Observer)
    raise ArgumentError, 'Expected `observer` to be a `Promise::Observer`'
  end

  @observers ||= []
  @observers.push(observer, on_fulfill_arg, on_reject_arg)
end

#syncObject



78
79
80
81
82
83
84
85
# File 'lib/promise.rb', line 78

def sync
  if pending?
    wait
    raise BrokenError if pending?
  end
  raise reason if rejected?
  value
end

#then(on_fulfill = nil, on_reject = nil, &block) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/promise.rb', line 56

def then(on_fulfill = nil, on_reject = nil, &block)
  on_fulfill ||= block
  next_promise = self.class.new

  case state
  when :fulfilled
    defer { next_promise.promise_fulfilled(value, on_fulfill) }
  when :rejected
    defer { next_promise.promise_rejected(reason, on_reject) }
  else
    next_promise.source = self
    subscribe(next_promise, on_fulfill, on_reject)
  end

  next_promise
end

#waitObject

Override to support sync on a promise without a source or to wait for deferred callbacks on the source



126
127
128
129
130
131
132
# File 'lib/promise.rb', line 126

def wait
  while source
    saved_source = source
    saved_source.wait
    break if saved_source.equal?(source)
  end
end