@@ -39,42 +39,22 @@ module JS
39
39
Null = JS . eval ( "return null" )
40
40
41
41
class PromiseScheduler
42
- Task = Struct . new ( :fiber , :status , :value )
43
-
44
- def initialize ( main_fiber )
45
- @tasks = [ ]
46
- @is_spinning = false
47
- @loop_fiber =
48
- Fiber . new do
49
- loop do
50
- while task = @tasks . shift
51
- task . fiber . transfer ( task . value , task . status )
52
- end
53
- @is_spinning = false
54
- main_fiber . transfer
55
- end
56
- end
42
+ def initialize ( loop )
43
+ @loop = loop
57
44
end
58
45
59
46
def await ( promise )
60
47
current = Fiber . current
61
48
promise . call (
62
49
:then ,
63
- -> ( value ) { enqueue Task . new ( current , :success , value ) } ,
64
- -> ( value ) { enqueue Task . new ( current , :failure , value ) }
50
+ -> ( value ) { current . transfer ( value , :success ) } ,
51
+ -> ( value ) { current . transfer ( value , :failure ) }
65
52
)
66
- value , status = @loop_fiber . transfer
53
+ raise "JS::Object#await can be called only from evalAsync" if @loop == current
54
+ value , status = @loop . transfer
67
55
raise JS ::Error . new ( value ) if status == :failure
68
56
value
69
57
end
70
-
71
- def enqueue ( task )
72
- @tasks << task
73
- unless @is_spinning
74
- @is_spinning = true
75
- JS . global . queueMicrotask -> { @loop_fiber . transfer }
76
- end
77
- end
78
58
end
79
59
80
60
@promise_scheduler = PromiseScheduler . new Fiber . current
@@ -120,8 +100,8 @@ def respond_to_missing?(sym, include_private)
120
100
# This method looks like a synchronous method, but it actually runs asynchronously using fibers.
121
101
# In other words, the next line to the `await` call at Ruby source will be executed after the
122
102
# promise will be resolved. However, it does not block JavaScript event loop, so the next line
123
- # to the ` RubyVM.eval` or `RubyVM. evalAsync` (in the case when no `await` operator before the
124
- # call expression) at JavaScript source will be executed without waiting for the promise.
103
+ # to the RubyVM.evalAsync` (in the case when no `await` operator before the call expression)
104
+ # at JavaScript source will be executed without waiting for the promise.
125
105
#
126
106
# The below example shows how the execution order goes. It goes in the order of "step N"
127
107
#
0 commit comments