@@ -39,42 +39,22 @@ module JS
3939 Null = JS . eval ( "return null" )
4040
4141 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
5744 end
5845
5946 def await ( promise )
6047 current = Fiber . current
6148 promise . call (
6249 :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 ) }
6552 )
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
6755 raise JS ::Error . new ( value ) if status == :failure
6856 value
6957 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
7858 end
7959
8060 @promise_scheduler = PromiseScheduler . new Fiber . current
@@ -120,8 +100,8 @@ def respond_to_missing?(sym, include_private)
120100 # This method looks like a synchronous method, but it actually runs asynchronously using fibers.
121101 # In other words, the next line to the `await` call at Ruby source will be executed after the
122102 # 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.
125105 #
126106 # The below example shows how the execution order goes. It goes in the order of "step N"
127107 #
0 commit comments