Annotate

util/promise.lua @ 13252:84c7779618b6

core.portmanager: Join strings broken into multiple lines Improves readability. Reduces line count. What's not to like? The code style and luacheck rules allows longer lines, and these strings aren't long enough to need breaking into multiple lines like this.
author Kim Alvefur <zash@zash.se>
date Sat, 29 Jul 2023 02:04:24 +0200
parent 12975:d10957394a3c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
12975
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12750
diff changeset
4 local xpcall = require "prosody.util.xpcall".xpcall;
12589
39ae08180c81 compat: Remove handling of Lua 5.1 location of 'unpack' function
Kim Alvefur <zash@zash.se>
parents: 11947
diff changeset
5 local unpack = table.unpack;
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 function _resolve(v)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 if is_promise(v) then
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 v:next(new_resolve_functions(p));
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 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
64 p.value = v;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 local function _reject(e)
9558
5fa73fbb047f util.promise: Remove the non-standard ability to pass a promise to reject()
Matthew Wild <mwild1@gmail.com>
parents: 9550
diff changeset
69 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
70 p.reason = e;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 return _resolve, _reject;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
76 local next_tick = function (f)
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
77 f();
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
78 end
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
79
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
80 local function new(f)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
81 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
82 if f then
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
83 next_tick(function()
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
84 local resolve, reject = new_resolve_functions(p);
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
85 local ok, ret = xpcall(f, debug.traceback, resolve, reject);
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
86 if not ok and p._state == "pending" then
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
87 reject(ret);
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
88 end
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
89 end);
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
90 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
91 return p;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 local function all(promises)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 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
96 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
97 local total = 0;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
98 for k, v in pairs(promises) do
11485
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
99 if is_promise(v) then
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
100 total = total + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
101 v:next(function (value)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
102 results[k] = value;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
103 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
104 if settled == total and loop_finished then
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
105 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
106 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
107 end, reject);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
108 else
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
109 results[k] = v;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
110 end
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end
11483
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
112 loop_finished = true;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
113 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
114 resolve(results);
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
115 end
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 end);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118
10922
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
119 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
120 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
121 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
122 local total = 0;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
123 for k, v in pairs(promises) do
11485
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
124 if is_promise(v) then
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
125 total = total + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
126 v:next(function (value)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
127 results[k] = { status = "fulfilled", value = value };
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
128 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
129 if settled == total and loop_finished then
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
130 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
131 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
132 end, function (e)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
133 results[k] = { status = "rejected", reason = e };
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
134 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
135 if settled == total and loop_finished then
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
136 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
137 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
138 end);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
139 else
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
140 results[k] = v;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
141 end
10922
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
142 end
11483
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
143 loop_finished = true;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
144 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
145 resolve(results);
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
146 end
10922
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
147 end);
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
148 end
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
149
11486
78d843faaffc util.promise: Switch order of parameters to join()
Matthew Wild <mwild1@gmail.com>
parents: 11485
diff changeset
150 local function join(handler, ...)
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
151 local promises, n = { ... }, select("#", ...);
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
152 return all(promises):next(function (results)
11486
78d843faaffc util.promise: Switch order of parameters to join()
Matthew Wild <mwild1@gmail.com>
parents: 11485
diff changeset
153 return handler(unpack(results, 1, n));
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
154 end);
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
155 end
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
156
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 local function race(promises)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 return new(function (resolve, reject)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 for i = 1, #promises do
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 promises[i]:next(resolve, reject);
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 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 local function resolve(v)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 return new(function (_resolve)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 _resolve(v);
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 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 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
172 return new(function (_, _reject)
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 _reject(v);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 end);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
9517
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
177 local function try(f)
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
178 return resolve():next(function () return f(); end);
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
179 end
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
180
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
181 function promise_methods:next(on_fulfilled, on_rejected)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
182 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
183 self:_next(on_fulfilled, on_rejected, resolve, reject);
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
184 end);
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
185 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
186
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
187 function promise_methods:catch(on_rejected)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
188 return self:next(nil, on_rejected);
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
189 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
190
9514
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
191 function promise_methods:finally(on_finally)
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
192 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
193 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
194 return self:next(_on_finally, _on_catch_finally);
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
195 end
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
196
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 return {
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 new = new;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 resolve = resolve;
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
200 join = join;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 reject = reject;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 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
203 all_settled = all_settled;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 race = race;
9517
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
205 try = try;
9548
a83afc22e9d7 util.promise: Export is_promise()
Matthew Wild <mwild1@gmail.com>
parents: 9546
diff changeset
206 is_promise = is_promise;
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
207 set_nexttick = function(new_next_tick) next_tick = new_next_tick; end;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 }