Skip to content

Commit c47e1a2

Browse files
authored
feat: add async.util.race to run funcs in race (#538)
1 parent 6bbfa69 commit c47e1a2

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

lua/plenary/async/util.lua

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,14 @@ M.join = function(async_fns)
7676
return results
7777
end
7878

79-
---Returns a future that when run will select the first async_function that finishes
80-
---@param async_funs table: The async_function that you want to select
79+
---Returns a result from the future that finishes at the first
80+
---@param async_functions table: The futures that you want to select
8181
---@return ...
82-
M.run_first = a.wrap(function(async_funs, step)
82+
M.run_first = a.wrap(function(async_functions, step)
8383
local ran = false
8484

85-
for _, future in ipairs(async_funs) do
86-
assert(type(future) == "function", "type error :: future must be function")
85+
for _, async_function in ipairs(async_functions) do
86+
assert(type(async_function) == "function", "type error :: future must be function")
8787

8888
local callback = function(...)
8989
if not ran then
@@ -92,10 +92,22 @@ M.run_first = a.wrap(function(async_funs, step)
9292
end
9393
end
9494

95-
future(callback)
95+
async_function(callback)
9696
end
9797
end, 2)
9898

99+
---Returns a result from the functions that finishes at the first
100+
---@param funcs table: The async functions that you want to select
101+
---@return ...
102+
M.race = function(funcs)
103+
local async_functions = vim.tbl_map(function(func)
104+
return function(callback)
105+
a.run(func, callback)
106+
end
107+
end, funcs)
108+
return M.run_first(async_functions)
109+
end
110+
99111
M.run_all = function(async_fns, callback)
100112
a.run(function()
101113
M.join(async_fns)

tests/plenary/async/util_spec.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,31 @@ describe("async await util", function()
4747
eq(ret, "didnt fail")
4848
end)
4949
end)
50+
51+
local function sleep(msec)
52+
return function()
53+
a.util.sleep(msec)
54+
return msec
55+
end
56+
end
57+
58+
describe("race", function()
59+
a.it("should return the first result", function()
60+
local funcs = vim.tbl_map(sleep, { 300, 400, 100, 200 })
61+
local result = a.util.race(funcs)
62+
eq(result, 100)
63+
end)
64+
end)
65+
66+
describe("run_first", function()
67+
a.it("should return the first result", function()
68+
local async_functions = vim.tbl_map(function(num)
69+
return function(callback)
70+
return a.run(sleep(num), callback)
71+
end
72+
end, { 300, 400, 100, 200 })
73+
local result = a.util.run_first(async_functions)
74+
eq(result, 100)
75+
end)
76+
end)
5077
end)

0 commit comments

Comments
 (0)