Software /
code /
prosody
Annotate
util/promise.lua @ 11484:a0120e935442
util.promise: Add join() convenience method
Usage: promise.join(p1, p2, function (result1, result2)
[...]
end)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 25 Mar 2021 14:28:38 +0000 |
parent | 11483:24ce9d380475 |
child | 11485:7d42ed3a8a40 |
rev | line source |
---|---|
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local promise_methods = {}; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local promise_mt = { __name = "promise", __index = promise_methods }; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
9562
acf74ad0b795
Many things: switch from hacky multi-arg xpcall implementations to a standard util.xpcall
Matthew Wild <mwild1@gmail.com>
parents:
9559
diff
changeset
|
4 local xpcall = require "util.xpcall".xpcall; |
11484
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
5 local unpack = table.unpack or unpack; --luacheck: ignore 113 |
9562
acf74ad0b795
Many things: switch from hacky multi-arg xpcall implementations to a standard util.xpcall
Matthew Wild <mwild1@gmail.com>
parents:
9559
diff
changeset
|
6 |
9515
2571c65b972f
util.promise: Add a string representation
Kim Alvefur <zash@zash.se>
parents:
9514
diff
changeset
|
7 function promise_mt:__tostring() |
2571c65b972f
util.promise: Add a string representation
Kim Alvefur <zash@zash.se>
parents:
9514
diff
changeset
|
8 return "promise (" .. (self._state or "invalid") .. ")"; |
2571c65b972f
util.promise: Add a string representation
Kim Alvefur <zash@zash.se>
parents:
9514
diff
changeset
|
9 end |
2571c65b972f
util.promise: Add a string representation
Kim Alvefur <zash@zash.se>
parents:
9514
diff
changeset
|
10 |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 local function is_promise(o) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 local mt = getmetatable(o); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 return mt == promise_mt; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
16 local function wrap_handler(f, resolve, reject, default) |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
17 if not f then |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
18 return default; |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
19 end |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
20 return function (param) |
9559
7c65e3f38e6e
util.promise: Switch from pcall to xpcall to get tracebacks on exceptions
Matthew Wild <mwild1@gmail.com>
parents:
9558
diff
changeset
|
21 local ok, ret = xpcall(f, debug.traceback, param); |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
22 if ok then |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
23 resolve(ret); |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
24 else |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
25 reject(ret); |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
26 end |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
27 return true; |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
28 end; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
31 local function next_pending(self, on_fulfilled, on_rejected, resolve, reject) |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
32 table.insert(self._pending_on_fulfilled, wrap_handler(on_fulfilled, resolve, reject, resolve)); |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
33 table.insert(self._pending_on_rejected, wrap_handler(on_rejected, resolve, reject, reject)); |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
36 local function next_fulfilled(promise, on_fulfilled, on_rejected, resolve, reject) -- luacheck: ignore 212/on_rejected |
9550
98de4c2e2627
util.promise: Fix missing parameters
Matthew Wild <mwild1@gmail.com>
parents:
9549
diff
changeset
|
37 wrap_handler(on_fulfilled, resolve, reject, resolve)(promise.value); |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
38 end |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
39 |
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
40 local function next_rejected(promise, on_fulfilled, on_rejected, resolve, reject) -- luacheck: ignore 212/on_fulfilled |
9550
98de4c2e2627
util.promise: Fix missing parameters
Matthew Wild <mwild1@gmail.com>
parents:
9549
diff
changeset
|
41 wrap_handler(on_rejected, resolve, reject, reject)(promise.reason); |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 local function promise_settle(promise, new_state, new_next, cbs, value) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 if promise._state ~= "pending" then |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 return; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 promise._state = new_state; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 promise._next = new_next; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 for _, cb in ipairs(cbs) do |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 cb(value); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 end |
9745
0dbb285f903e
util.promise: Remove references to callbacks after settling promise
Kim Alvefur <zash@zash.se>
parents:
9562
diff
changeset
|
53 -- No need to keep references to callbacks |
0dbb285f903e
util.promise: Remove references to callbacks after settling promise
Kim Alvefur <zash@zash.se>
parents:
9562
diff
changeset
|
54 promise._pending_on_fulfilled = nil; |
0dbb285f903e
util.promise: Remove references to callbacks after settling promise
Kim Alvefur <zash@zash.se>
parents:
9562
diff
changeset
|
55 promise._pending_on_rejected = nil; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 return true; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 local function new_resolve_functions(p) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 local resolved = false; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 local function _resolve(v) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 if resolved then return; end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 resolved = true; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 if is_promise(v) then |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 v:next(new_resolve_functions(p)); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 elseif promise_settle(p, "fulfilled", next_fulfilled, p._pending_on_fulfilled, v) then |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 p.value = v; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 local function _reject(e) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 if resolved then return; end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 resolved = true; |
9558
5fa73fbb047f
util.promise: Remove the non-standard ability to pass a promise to reject()
Matthew Wild <mwild1@gmail.com>
parents:
9550
diff
changeset
|
74 if promise_settle(p, "rejected", next_rejected, p._pending_on_rejected, e) then |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 p.reason = e; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 return _resolve, _reject; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 |
9513
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
81 local function new(f) |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
82 local p = setmetatable({ _state = "pending", _next = next_pending, _pending_on_fulfilled = {}, _pending_on_rejected = {} }, promise_mt); |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
83 if f then |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
84 local resolve, reject = new_resolve_functions(p); |
11210
75636bf13bf0
util.promise: Use xpcall() for promise function to preserve tracebacks
Matthew Wild <mwild1@gmail.com>
parents:
9562
diff
changeset
|
85 local ok, ret = xpcall(f, debug.traceback, resolve, reject); |
9513
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
86 if not ok and p._state == "pending" then |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
87 reject(ret); |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
88 end |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
89 end |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
90 return p; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 local function all(promises) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 return new(function (resolve, reject) |
11483
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
95 local settled, results, loop_finished = 0, {}, false; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
96 local total = 0; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
97 for k, v in pairs(promises) do |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
98 total = total + 1; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
99 v:next(function (value) |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
100 results[k] = value; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
101 settled = settled + 1; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
102 if settled == total and loop_finished then |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 resolve(results); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 end, reject); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 end |
11483
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
107 loop_finished = true; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
108 if settled == total then |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
109 resolve(results); |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
110 end |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 end); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 |
10922
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
114 local function all_settled(promises) |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
115 return new(function (resolve) |
11483
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
116 local settled, results, loop_finished = 0, {}, false; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
117 local total = 0; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
118 for k, v in pairs(promises) do |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
119 total = total + 1; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
120 v:next(function (value) |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
121 results[k] = { status = "fulfilled", value = value }; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
122 settled = settled + 1; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
123 if settled == total and loop_finished then |
10922
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
124 resolve(results); |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
125 end |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
126 end, function (e) |
11483
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
127 results[k] = { status = "rejected", reason = e }; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
128 settled = settled + 1; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
129 if settled == total and loop_finished then |
10922
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
130 resolve(results); |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
131 end |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
132 end); |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
133 end |
11483
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
134 loop_finished = true; |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
135 if settled == total then |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
136 resolve(results); |
24ce9d380475
util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents:
11211
diff
changeset
|
137 end |
10922
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
138 end); |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
139 end |
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
140 |
11484
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
141 local function join(...) |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
142 local promises, n = { ... }, select("#", ...); |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
143 local handler = promises[n]; |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
144 promises[n] = nil; |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
145 return all(promises):next(function (results) |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
146 return handler(unpack(results, 1, n - 1)); |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
147 end); |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
148 end |
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
149 |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 local function race(promises) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
151 return new(function (resolve, reject) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
152 for i = 1, #promises do |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
153 promises[i]:next(resolve, reject); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
154 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 end); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
156 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
158 local function resolve(v) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
159 return new(function (_resolve) |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
160 _resolve(v); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 end); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
162 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
164 local function reject(v) |
9510
8ef46d09386a
util.promise: Fix promise.reject() to return a rejected promise, and fix buggy test for it
Matthew Wild <mwild1@gmail.com>
parents:
9456
diff
changeset
|
165 return new(function (_, _reject) |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
166 _reject(v); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
167 end); |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
168 end |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
169 |
9517
b1c6ede17592
util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents:
9515
diff
changeset
|
170 local function try(f) |
b1c6ede17592
util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents:
9515
diff
changeset
|
171 return resolve():next(function () return f(); end); |
b1c6ede17592
util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents:
9515
diff
changeset
|
172 end |
b1c6ede17592
util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents:
9515
diff
changeset
|
173 |
9513
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
174 function promise_methods:next(on_fulfilled, on_rejected) |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
175 return new(function (resolve, reject) --luacheck: ignore 431/resolve 431/reject |
9549
800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
Matthew Wild <mwild1@gmail.com>
parents:
9548
diff
changeset
|
176 self:_next(on_fulfilled, on_rejected, resolve, reject); |
9513
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
177 end); |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
178 end |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
179 |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
180 function promise_methods:catch(on_rejected) |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
181 return self:next(nil, on_rejected); |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
182 end |
4f4f9823bd1d
util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents:
9512
diff
changeset
|
183 |
9514
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
184 function promise_methods:finally(on_finally) |
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
185 local function _on_finally(value) on_finally(); return value; end |
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
186 local function _on_catch_finally(err) on_finally(); return reject(err); end |
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
187 return self:next(_on_finally, _on_catch_finally); |
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
188 end |
9db707a86a25
util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents:
9513
diff
changeset
|
189 |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
190 return { |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
191 new = new; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
192 resolve = resolve; |
11484
a0120e935442
util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents:
11483
diff
changeset
|
193 join = join; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
194 reject = reject; |
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
195 all = all; |
10922
7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents:
9745
diff
changeset
|
196 all_settled = all_settled; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
197 race = race; |
9517
b1c6ede17592
util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents:
9515
diff
changeset
|
198 try = try; |
9548
a83afc22e9d7
util.promise: Export is_promise()
Matthew Wild <mwild1@gmail.com>
parents:
9546
diff
changeset
|
199 is_promise = is_promise; |
9456
d54a0e129af8
util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
200 } |