-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use coroutines for async/await bevavior (#2)
* use coroutines for async/await bevavior * add missing files * wip * working sync/await * tests * tests * use await as function arg * workign reject/error * interop test * rename * add error testcase * docs --------- Co-authored-by: BuckarooBanzay <[email protected]>
- Loading branch information
1 parent
ccbd4c3
commit bf75f46
Showing
5 changed files
with
174 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
|
||
local err_symbol = {} | ||
|
||
local function await(p) | ||
assert(coroutine.running(), "running inside a Promise.async() call") | ||
local result = nil | ||
local err = nil | ||
local finished = false | ||
|
||
p:next(function(...) | ||
result = {...} | ||
finished = true | ||
end):catch(function(e) | ||
err = e | ||
finished = true | ||
end) | ||
|
||
while true do | ||
if finished then | ||
if err then | ||
return coroutine.yield({ err = err, err_symbol = err_symbol }) | ||
else | ||
return unpack(result) | ||
end | ||
else | ||
coroutine.yield() | ||
end | ||
end | ||
end | ||
|
||
function Promise.async(fn) | ||
local t = coroutine.create(fn) | ||
local p = Promise.new() | ||
|
||
local step = nil | ||
local result = nil | ||
local cont = nil | ||
local _ = nil | ||
step = function() | ||
if coroutine.status(t) == "suspended" then | ||
cont, result = coroutine.resume(t, await) | ||
if not cont then | ||
-- error in first async() level | ||
p:reject(result) | ||
end | ||
if type(result) == "table" and result.err_symbol == err_symbol then | ||
-- error in await() call | ||
p:reject(result.err) | ||
return | ||
end | ||
minetest.after(0, step) | ||
else | ||
-- last result from resume was the return value | ||
p:resolve(result) | ||
end | ||
end | ||
step() | ||
|
||
return p | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
|
||
mtt.register("Promise.async", function(callback) | ||
local p = Promise.async(function(await) | ||
local v = await(Promise.after(0, 42)) | ||
assert(v == 42) | ||
local v1 = await(Promise.resolved(666)) | ||
assert(v1 == 666) | ||
return 99 | ||
end) | ||
|
||
p:next(function(v) | ||
assert(v == 99) | ||
callback() | ||
end) | ||
end) | ||
|
||
mtt.register("Promise.async interop", function() | ||
return Promise.async(function(await) | ||
return await(Promise.async(function() | ||
local v = await(Promise.resolved(42)) | ||
assert(v == 42) | ||
end)) | ||
end) | ||
end) | ||
|
||
mtt.register("Promise.async simple", function() | ||
return Promise.async(function(await) | ||
local v = await(Promise.resolved(42)) | ||
assert(v == 42) | ||
end) | ||
end) | ||
|
||
mtt.register("Promise.async with handle_async", function() | ||
return Promise.async(function(await) | ||
local v = await(Promise.resolved(42)) | ||
assert(v == 42) | ||
v = await(Promise.handle_async(function() return 100 end)) | ||
assert(v == 100) | ||
end) | ||
end) | ||
|
||
mtt.register("Promise.async rejected", function(callback) | ||
local p = Promise.async(function(await) | ||
await(Promise.rejected("my-err")) | ||
end) | ||
|
||
p:catch(function(e) | ||
assert(type(e) == "string") | ||
callback() | ||
end) | ||
end) | ||
|
||
mtt.register("Promise.async error", function(callback) | ||
local p = Promise.async(function() | ||
error("stuff") | ||
end) | ||
|
||
p:catch(function(e) | ||
-- "/home/user/.minetest/mods/promise/async.spec.lua:55: stuff" | ||
assert(type(e) == "string") | ||
callback() | ||
end) | ||
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters