-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample.lua
More file actions
79 lines (68 loc) · 2.83 KB
/
Copy pathexample.lua
File metadata and controls
79 lines (68 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
--- Showcase of the Promise API. Mirrors what you can do with a JavaScript
--- Promise, plus the coroutine-based `:Await()` / `async` / `await` sugar.
require "promise.class.lua"; -- Implement your own require path
--- A fake async job: counts to `target`, then calls back. Half the time it
--- "fails" to demonstrate rejection paths.
---@param target integer
---@param callback fun(ok: boolean, count: integer)
local function count_async(target, callback)
local count = 0;
while (count < target) do
count = count + 1;
end
callback(math.random(1, 2) == 1, count);
end
--- 1. Executor style — wrap a callback API into a promise.
---@return Promise
local function count(target)
return Promise(function(resolve, reject)
count_async(target, function(ok, value)
if (ok) then
resolve(value);
else
reject(("count(%d) failed"):format(target));
end
end);
end);
end
--- 2. Deferred style — get a handle now, settle it later.
---@return Promise
local function count_deferred(target)
local promise <const> = Promise();
count_async(target, function(_, value) promise:Resolve(value); end);
return promise;
end
-- Chaining: each :Then receives the previous return value.
count(10)
:Then(function(value) return value * 2; end)
:Then(function(doubled) print(("chained result: %d"):format(doubled)); end)
:Catch(function(reason) print(("chain failed: %s"):format(reason)); end)
:Finally(function() print("chain settled"); end);
-- Combinators, JavaScript-style.
Promise.all({ count(5), count(10), count_deferred(15) })
:Then(function(values) print(("all done: %d/%d/%d"):format(values[1], values[2], values[3])); end)
:Catch(function(reason) print(("one of them failed: %s"):format(reason)); end);
Promise.allSettled({ count(5), count(10) })
:Then(function(results)
for i, r in ipairs(results) do
print(("[%d] %s -> %s"):format(i, r.status, tostring(r.value or r.reason)));
end
end);
Promise.race({ count(5), count(50) })
:Then(function(winner) print(("race winner: %d"):format(winner)); end);
-- Sequential async/await flow inside a coroutine. `async` itself returns a
-- promise resolving to the function's return value.
async(function()
local a <const> = count(5):Await();
local b <const> = await(count_deferred(10)); -- global await works on any thenable
return a + b;
end)
:Then(function(total) print(("async total: %d"):format(total)); end)
:Catch(function(reason) print(("async failed: %s"):format(reason)); end);
-- Timers (require a scheduler installed via Promise.SetTimer).
async(function()
Promise.delay(1000):Await();
print("one second later");
end);
count(100):Timeout(2000, "took too long")
:Catch(function(reason) print(("timed out: %s"):format(reason)); end);