Class: Promise

Inherits:
Object
  • Object
show all
Defined in:
lib/isomorfeus/promise.rb

Overview

Direct Known Subclasses

Trace, When

Defined Under Namespace

Classes: Trace, When

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(action = {}) ⇒ Promise

Returns a new instance of Promise.



18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/isomorfeus/promise.rb', line 18

def initialize(action = {})
  @action = action

  @realized  = false
  @exception = false
  @value     = nil
  @error     = nil
  @delayed   = false

  @prev = nil
  @next = []
end

Instance Attribute Details

#errorObject (readonly)

Returns the value of attribute error.



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

def error
  @error
end

#nextObject (readonly)

Returns the value of attribute next.



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

def next
  @next
end

#prevObject (readonly)

Returns the value of attribute prev.



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

def prev
  @prev
end

Class Method Details

.error(value) ⇒ Object



8
9
10
# File 'lib/isomorfeus/promise.rb', line 8

def self.error(value)
  new.reject(value)
end

.value(value) ⇒ Object



4
5
6
# File 'lib/isomorfeus/promise.rb', line 4

def self.value(value)
  new.resolve(value)
end

.when(*promises) ⇒ Object



12
13
14
# File 'lib/isomorfeus/promise.rb', line 12

def self.when(*promises)
  When.new(promises)
end

Instance Method Details

#<<(promise) ⇒ Object



74
75
76
77
78
# File 'lib/isomorfeus/promise.rb', line 74

def <<(promise)
  @prev = promise

  self
end

#>>(promise) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/isomorfeus/promise.rb', line 80

def >>(promise)
  @next << promise

  if exception?
    promise.reject(@delayed[0])
  elsif resolved?
    promise.resolve(@delayed ? @delayed[0] : value)
  elsif rejected?
    if !@action.has_key?(:failure) || Promise === (@delayed ? @delayed[0] : @error)
      promise.reject(@delayed ? @delayed[0] : error)
    elsif promise.action.include?(:always)
      promise.reject(@delayed ? @delayed[0] : error)
    end
  end

  self
end

#^(promise) ⇒ Object



67
68
69
70
71
72
# File 'lib/isomorfeus/promise.rb', line 67

def ^(promise)
  promise << self
  self    >> promise

  promise
end

#act?Boolean

Returns:

  • (Boolean)


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

def act?
  @action.has_key?(:success) || @action.has_key?(:always)
end

#actionObject



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

def action
  @action.keys
end

#always(&block) ⇒ Object Also known as: finally, ensure



200
201
202
# File 'lib/isomorfeus/promise.rb', line 200

def always(&block)
  self ^ Promise.new(always: block)
end

#always!(&block) ⇒ Object Also known as: finally!, ensure!



204
205
206
207
# File 'lib/isomorfeus/promise.rb', line 204

def always!(&block)
  there_can_be_only_one!
  always(&block)
end

#exception!(error) ⇒ Object



168
169
170
171
172
# File 'lib/isomorfeus/promise.rb', line 168

def exception!(error)
  @exception = true

  reject!(error)
end

#exception?Boolean

Returns:

  • (Boolean)


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

def exception?
  @exception
end

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



186
187
188
# File 'lib/isomorfeus/promise.rb', line 186

def fail(&block)
  self ^ Promise.new(failure: block)
end

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



190
191
192
193
# File 'lib/isomorfeus/promise.rb', line 190

def fail!(&block)
  there_can_be_only_one!
  fail(&block)
end

#inspectObject



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/isomorfeus/promise.rb', line 229

def inspect
  result = "#<#{self.class}(#{object_id})"

  if @next.any?
    result += " >> #{@next.inspect}"
  end

  if realized?
    result += ": #{(@value || @error).inspect}>"
  else
    result += ">"
  end

  result
end

#pending?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/isomorfeus/promise.rb', line 63

def pending?
  !realized?
end

#realized?Boolean

Returns:

  • (Boolean)


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

def realized?
  !!@realized
end

#reject(value = nil) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/isomorfeus/promise.rb', line 131

def reject(value = nil)
  if realized?
    raise ArgumentError, 'the promise has already been realized'
  end

  if Promise === value
    return (value << @prev) ^ self
  end

  begin
    if block = @action[:failure] || @action[:always]
      value = block.call(value)
    end

    if @action.has_key?(:always)
      resolve!(value)
    else
      reject!(value)
    end
  rescue Exception => e
    exception!(e)
  end

  self
end

#reject!(value) ⇒ Object



157
158
159
160
161
162
163
164
165
166
# File 'lib/isomorfeus/promise.rb', line 157

def reject!(value)
  @realized = :reject
  @error    = value

  if @next.any?
    @next.each { |p| p.reject(value) }
  else
    @delayed = [value]
  end
end

#rejected?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/isomorfeus/promise.rb', line 59

def rejected?
  @realized == :reject
end

#resolve(value = nil) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/isomorfeus/promise.rb', line 98

def resolve(value = nil)
  if realized?
    raise ArgumentError, 'the promise has already been realized'
  end

  if Promise === value
    return (value << @prev) ^ self
  end

  begin
    if block = @action[:success] || @action[:always]
      value = block.call(value)
    end

    resolve!(value)
  rescue Exception => e
    exception!(e)
  end

  self
end

#resolve!(value) ⇒ Object



120
121
122
123
124
125
126
127
128
129
# File 'lib/isomorfeus/promise.rb', line 120

def resolve!(value)
  @realized = :resolve
  @value    = value

  if @next.any?
    @next.each { |p| p.resolve(value) }
  else
    @delayed = [value]
  end
end

#resolved?Boolean

Returns:

  • (Boolean)


55
56
57
# File 'lib/isomorfeus/promise.rb', line 55

def resolved?
  @realized == :resolve
end

#then(&block) ⇒ Object Also known as: do



174
175
176
# File 'lib/isomorfeus/promise.rb', line 174

def then(&block)
  self ^ Promise.new(success: block)
end

#then!(&block) ⇒ Object Also known as: do!



178
179
180
181
# File 'lib/isomorfeus/promise.rb', line 178

def then!(&block)
  there_can_be_only_one!
  self.then(&block)
end

#there_can_be_only_one!Object



223
224
225
226
227
# File 'lib/isomorfeus/promise.rb', line 223

def there_can_be_only_one!
  if @next.any?
    raise ArgumentError, 'a promise has already been chained'
  end
end

#trace(depth = nil, &block) ⇒ Object



214
215
216
# File 'lib/isomorfeus/promise.rb', line 214

def trace(depth = nil, &block)
  self ^ Trace.new(depth, block)
end

#trace!(*args, &block) ⇒ Object



218
219
220
221
# File 'lib/isomorfeus/promise.rb', line 218

def trace!(*args, &block)
  there_can_be_only_one!
  trace(*args, &block)
end

#valueObject



31
32
33
34
35
36
37
# File 'lib/isomorfeus/promise.rb', line 31

def value
  if Promise === @value
    @value.value
  else
    @value
  end
end