![](/img/trans.png)
[英]Ruby: Repeating a Method Multiple Times and Collecting Results in an Array
[英]Ruby 3 collecting results from multiple scheduled fibers
Ruby 3 引入了Fiber.schedule
來並發調度異步任務。
與這個問題(關於線程並發)中的問題類似,我想要一種在光纖調度程序上啟動多個並發任務的方法,一旦它們都被安排好等待它們的組合結果,有點等同於Promise.all
in JavaScript。
我可以想出這種天真的方法:
require 'async'
def io_work(t)
sleep t
:ok
end
Async do
results = []
[0.1, 0.3, 'cow'].each_with_index do |t, i|
n = i + 1
Fiber.schedule do
puts "Starting fiber #{n}\n"
result = io_work t
puts "Done working for #{t} seconds in fiber #{n}"
results << [n, result]
rescue
puts "Execution failed in fiber #{n}"
results << [n, :error]
end
end
# await combined results
sleep 0.1 until results.size >= 3
puts "Results: #{results}"
end
有沒有更簡單的結構可以做同樣的事情?
由於Async
任務已經安排好,我不確定您是否需要所有這些。
如果您只想等待所有項目完成,您可以使用Async::Barrier
例子:
require 'async'
require 'async/barrier'
def io_work(t)
sleep t
:ok
end
Async do
barrier = Async::Barrier.new
results = []
[1, 0.3, 'cow'].each.with_index(1) do |data, idx|
barrier.async do
results << begin
puts "Starting task #{idx}\n"
result = io_work data
puts "Done working for #{data} seconds in task #{idx}"
[idx,result]
rescue
puts "Execution failed in task #{idx}"
[idx, :error]
end
end
end
barrier.wait
puts "Results: #{results}"
end
根據sleep
值,這將輸出
Starting task 1
Starting task 2
Starting task 3
Execution failed in task 3
Done working for 0.3 seconds in task 2
Done working for 1 seconds in task 1
Results: [[3, :error], [2, :ok], [1, :ok]]
barrier.wait
會等到所有異步任務完成,沒有它輸出會是這樣的
Starting fiber 1
Starting fiber 2
Starting fiber 3
Execution failed in fiber 3
Results: [[3, :error]]
Done working for 0.3 seconds in fiber 2
Done working for 1 seconds in fiber 1
我對解決方案的人體工程學不太滿意,所以我制作了寶石纖維收集器來解決這個問題。
免責聲明:我正在描述一個我是作者的圖書館
問題場景中的示例用法:
require 'async'
require 'fiber/collector'
def io_work(t)
sleep t
:ok
end
Async do
Fiber::Collector.schedule { io_work(1) }.and { io_work(0.3) }.all
end.wait
# => [:ok, :ok]
Async do
Fiber::Collector.schedule { io_work(1) }.and { io_work(0.3) }.and { io_work('cow') }.all
end.wait
# => raises error
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.