Class: Promise

Inherits:
Object show all
Defined in:
lib/volt/utils/promise_extensions.rb

Overview

A temp patch for promises until github.com/opal/opal/pull/725 is released.

Defined Under Namespace

Classes: UnrealizedPromiseException

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/volt/utils/promise_extensions.rb', line 13

def method_missing(method_name, *args, &block)
  if respond_to_missing?(method_name)
    promise = self.then do |value|
      value.send(method_name, *args, &block)
    end

    promise
  else
    super
  end
end

Instance Method Details

#each(&block) ⇒ Object

Allow .each to be called directly on promises

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
# File 'lib/volt/utils/promise_extensions.rb', line 26

def each(&block)
  raise ArgumentError, 'no block given' unless block

  self.then do |val|
    val.each(&block)
  end
end

#exception!(error) ⇒ Object



68
69
70
71
72
73
74
75
# File 'lib/volt/utils/promise_extensions.rb', line 68

def exception!(error)
  if error.is_a?(RSpec::Expectations::ExpectationNotMetError)
    raise error
  end
  @exception = true

  reject!(error)
end

#inspectObject

Improve #inspect to not show nested promises.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/volt/utils/promise_extensions.rb', line 35

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

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

  if realized?
    value = value_or_error

    loop do
      if value.is_a?(Promise) && value.realized?
        value = value.value_or_error
      else
        break
      end
    end

    result += ": #{value.inspect}>"
  else
    result += ">"
  end

  result
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

We made a choice not to support comparitors and << and >> on method_missing on Promises. This makes it easier to understand what promise proxying does and how it works. It also prevents confusing situations where you try to

compare two Promises for example. The cost though is more code to do

comparisons, but we feel it is worth it.

Returns:



9
10
11
# File 'lib/volt/utils/promise_extensions.rb', line 9

def respond_to_missing?(method_name, include_private = false)
  !!(method_name =~ /[a-z_]\w*[?!=]?/)
end

#syncObject

Waits for the promise to be realized (resolved or rejected), then returns the resolved value or raises the rejection error. .sync only works on the server (not in opal), and will raise a warning if on the client.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/volt/utils/promise_extensions.rb', line 100

def sync
  raise ".sync can only be used on the server" if Volt.client?

  result = nil
  error = nil

  self.then do |val|
    result = val
  end.fail do |err|
    error = err
  end

  if error
    if error.is_a?(RSpec::Expectations::ExpectationNotMetError)
      # re-raise
      raise error
    end
    err_str = "Exception in Promise at .sync: #{error.inspect}"
    err_str += error.backtrace.join("\n") if error.respond_to?(:backtrace)
    Volt.logger.error(err_str)

    # The fail method in Promise is already defined, to re-raise the error,
    # we send fail
    Object.send(:fail, error)
  else
    return result
  end
end

#to_json(*args, &block) ⇒ Object

Forward to resolved value



79
80
81
# File 'lib/volt/utils/promise_extensions.rb', line 79

def to_json(*args, &block)
  self.then {|v| v.to_json(*args, &block) }
end

#unwrapObject

unwrap lets you return a value or raise an exceptoin on a realized promise. An exception will be raised if the promise is not realized yet.



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/volt/utils/promise_extensions.rb', line 85

def unwrap
  if realized?
    if resolved?
      value
    else
      Object.send(:fail, error)
    end
  else
    raise UnrealizedPromiseException, "#unwrap called on a promise that has yet to be realized."
  end
end

#value_or_errorObject



61
62
63
# File 'lib/volt/utils/promise_extensions.rb', line 61

def value_or_error
  @value || @error
end