Annotate

util/promise.lua @ 12094:84fd6a79cda7

adminstream: fire disconnected event on lower layer disconnect This may in theory cause multiple disconnect events for the adminstream client, if the only code using that wasn't calling os.exit right away. Hence, this should be a good enough partial fix for #1671. It is not a full fix, because the shell will only notice the disconnect after one has hit enter in the input; until then, it is stuck in a read() call to stdin and completely oblivious to the disconnect.
author Jonas Schäfer <jonas@wielicki.name>
date Tue, 21 Dec 2021 21:23:01 +0100
parent 11947:073e53b72792
child 12589:39ae08180c81
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
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
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
81 local next_tick = function (f)
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
82 f();
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
83 end
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
84
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
85 local function new(f)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
86 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
87 if f then
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
88 next_tick(function()
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
89 local resolve, reject = new_resolve_functions(p);
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
90 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
91 if not ok and p._state == "pending" then
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
92 reject(ret);
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
93 end
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
94 end);
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
95 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
96 return p;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 local function all(promises)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 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
101 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
102 local total = 0;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
103 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
104 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
105 total = total + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
106 v:next(function (value)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
107 results[k] = value;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
108 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
109 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
110 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
111 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
112 end, reject);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
113 else
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
114 results[k] = v;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
115 end
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 end
11483
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
117 loop_finished = true;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
118 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
119 resolve(results);
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
120 end
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 end);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123
10922
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
124 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
125 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
126 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
127 local total = 0;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
128 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
129 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
130 total = total + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
131 v:next(function (value)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
132 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
133 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
134 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
135 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
136 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
137 end, function (e)
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
138 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
139 settled = settled + 1;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
140 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
141 resolve(results);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
142 end
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
143 end);
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
144 else
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
diff changeset
145 results[k] = v;
7d42ed3a8a40 util.promise: all()/all_settled() pass through non-promise values
Matthew Wild <mwild1@gmail.com>
parents: 11484
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
11483
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
148 loop_finished = true;
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
149 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
150 resolve(results);
24ce9d380475 util.promise: Add support for arbitrary keys in all()/all_settled()
Matthew Wild <mwild1@gmail.com>
parents: 11211
diff changeset
151 end
10922
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
152 end);
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
153 end
7d3dbb9eb3eb util.promise: Add all_settled, which follows semantics of allSettled from ES2020
Matthew Wild <mwild1@gmail.com>
parents: 9745
diff changeset
154
11486
78d843faaffc util.promise: Switch order of parameters to join()
Matthew Wild <mwild1@gmail.com>
parents: 11485
diff changeset
155 local function join(handler, ...)
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
156 local promises, n = { ... }, select("#", ...);
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
157 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
158 return handler(unpack(results, 1, n));
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
159 end);
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
160 end
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
161
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 local function race(promises)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 return new(function (resolve, reject)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 for i = 1, #promises do
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 promises[i]:next(resolve, reject);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 end
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
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 local function resolve(v)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 return new(function (_resolve)
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 _resolve(v);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 end);
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
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 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
177 return new(function (_, _reject)
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 _reject(v);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 end);
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 end
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181
9517
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
182 local function try(f)
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
183 return resolve():next(function () return f(); end);
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
184 end
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
185
9513
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
186 function promise_methods:next(on_fulfilled, on_rejected)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
187 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
188 self:_next(on_fulfilled, on_rejected, resolve, reject);
9513
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 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
191
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
192 function promise_methods:catch(on_rejected)
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
193 return self:next(nil, on_rejected);
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
194 end
4f4f9823bd1d util.promise: Some code relocation
Matthew Wild <mwild1@gmail.com>
parents: 9512
diff changeset
195
9514
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
196 function promise_methods:finally(on_finally)
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
197 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
198 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
199 return self:next(_on_finally, _on_catch_finally);
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
200 end
9db707a86a25 util.promise: Add promise:finally()
Matthew Wild <mwild1@gmail.com>
parents: 9513
diff changeset
201
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 return {
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 new = new;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 resolve = resolve;
11484
a0120e935442 util.promise: Add join() convenience method
Matthew Wild <mwild1@gmail.com>
parents: 11483
diff changeset
205 join = join;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 reject = reject;
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 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
208 all_settled = all_settled;
9456
d54a0e129af8 util.promise: ES6-like API for promises
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 race = race;
9517
b1c6ede17592 util.promise: Add promise.try()
Matthew Wild <mwild1@gmail.com>
parents: 9515
diff changeset
210 try = try;
9548
a83afc22e9d7 util.promise: Export is_promise()
Matthew Wild <mwild1@gmail.com>
parents: 9546
diff changeset
211 is_promise = is_promise;
11947
073e53b72792 util.promise: Support delayed promise execution
Kim Alvefur <zash@zash.se>
parents: 11486
diff changeset
212 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
213 }