Skip to content

Commit

Permalink
Add with_resolvers()
Browse files Browse the repository at this point in the history
  • Loading branch information
notomo committed Aug 23, 2024
1 parent 596f7a5 commit 69f5b21
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 4 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ local do_async = function(i)
end)
end

local do_async2 = function(i)
local promise, resolve, reject = Promise.with_resolvers()
vim.defer_fn(function()
if i % 2 == 1 then
resolve("ok" .. i)
else
reject("error")
end
end, i * 10)
return promise
end

Promise.all({ do_async(1), do_async(3), do_async(5) }):next(function(value)
assert(vim.deep_equal(value, { "ok1", "ok3", "ok5" }))
end)
Expand All @@ -57,7 +69,7 @@ Promise.any({ do_async(1), do_async(2) }):next(function(value)
assert(value == "ok1")
end)

Promise.all_settled({ do_async(1), do_async(2) }):next(function(values)
Promise.all_settled({ do_async(1), do_async2(2) }):next(function(values)
assert(values[1].value == "ok1")
assert(values[1].status == "fulfilled")
assert(values[2].reason == "error")
Expand Down
22 changes: 21 additions & 1 deletion doc/promise.nvim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ all_settled({list}) *promise.all_settled()*
Return: ~
(Promise)

with_resolvers() *promise.with_resolvers()*
Equivalents to JavaScript's Promise.withResolvers.

Return: ~
(Promise)
(fun(...:any)) resolve
(fun(...:any)) reject

==============================================================================
EXAMPLES *promise.nvim-EXAMPLES*

Expand Down Expand Up @@ -142,6 +150,18 @@ EXAMPLES *promise.nvim-EXAMPLES*
end)
end

local do_async2 = function(i)
local promise, resolve, reject = Promise.with_resolvers()
vim.defer_fn(function()
if i % 2 == 1 then
resolve("ok" .. i)
else
reject("error")
end
end, i * 10)
return promise
end

Promise.all({ do_async(1), do_async(3), do_async(5) }):next(function(value)
assert(vim.deep_equal(value, { "ok1", "ok3", "ok5" }))
end)
Expand All @@ -154,7 +174,7 @@ EXAMPLES *promise.nvim-EXAMPLES*
assert(value == "ok1")
end)

Promise.all_settled({ do_async(1), do_async(2) }):next(function(values)
Promise.all_settled({ do_async(1), do_async2(2) }):next(function(values)
assert(values[1].value == "ok1")
assert(values[1].status == "fulfilled")
assert(values[2].reason == "error")
Expand Down
13 changes: 13 additions & 0 deletions lua/promise/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,17 @@ function Promise.all_settled(list)
end)
end

--- Equivalents to JavaScript's Promise.withResolvers.
--- @return Promise
--- @return fun(...:any) # resolve
--- @return fun(...:any) # reject
function Promise.with_resolvers()
local resolve, reject
local promise = Promise.new(function(res, rej)
resolve = res
reject = rej
end)
return promise, resolve, reject
end

return Promise
16 changes: 14 additions & 2 deletions spec/lua/promise/example.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ local do_async = function(i)
end)
end

local do_async2 = function(i)
local promise, resolve, reject = Promise.with_resolvers()
vim.defer_fn(function()
if i % 2 == 1 then
resolve("ok" .. i)
else
reject("error")
end
end, i * 10)
return promise
end

Promise.all({ do_async(1), do_async(3), do_async(5) }):next(function(value)
assert(vim.deep_equal(value, { "ok1", "ok3", "ok5" }))
end)
Expand All @@ -49,14 +61,14 @@ Promise.any({ do_async(1), do_async(2) }):next(function(value)
assert(value == "ok1")
end)

Promise.all_settled({ do_async(1), do_async(2) }):next(function(values)
Promise.all_settled({ do_async(1), do_async2(2) }):next(function(values)
assert(values[1].value == "ok1")
assert(values[1].status == "fulfilled")
assert(values[2].reason == "error")
assert(values[2].status == "rejected")
end)
local wait = { finished = false }
do_async(33):next(function() end):next(function() end):next(function() end):next(function() end):next(function()
do_async2(33):next(function() end):next(function() end):next(function() end):next(function() end):next(function()
wait.finished = true
end)

Expand Down
41 changes: 41 additions & 0 deletions spec/lua/promise/with_resolvers_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
local helper = require("promise.test.helper")
local Promise = helper.require("promise")

describe("Promise.with_resolvers()", function()
before_each(helper.before_each)
after_each(helper.after_each)

it("returns promise with resolve", function()
local got
local on_finished = helper.on_finished()
local promise, resolve = Promise.with_resolvers()

vim.schedule(function()
resolve("ok")
end)
promise:next(function(v)
got = v
on_finished()
end)
on_finished:wait()

assert.is_same("ok", got)
end)

it("returns promise with reject", function()
local got
local on_finished = helper.on_finished()
local promise, _, reject = Promise.with_resolvers()

vim.schedule(function()
reject("error")
end)
promise:catch(function(err)
got = err
on_finished()
end)
on_finished:wait()

assert.is_same("error", got)
end)
end)

0 comments on commit 69f5b21

Please sign in to comment.