Software /
code /
prosody
Diff
util/promise.lua @ 9549:800c274928bf
util.promise: Ensure chained promises always receive a value/rejection even if an intermediate promise has no handlers
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 25 Oct 2018 14:38:00 +0100 |
parent | 9548:a83afc22e9d7 |
child | 9550:98de4c2e2627 |
line wrap: on
line diff
--- a/util/promise.lua Thu Oct 25 14:19:27 2018 +0100 +++ b/util/promise.lua Thu Oct 25 14:38:00 2018 +0100 @@ -10,17 +10,32 @@ return mt == promise_mt; end -local function next_pending(self, on_fulfilled, on_rejected) - table.insert(self._pending_on_fulfilled, on_fulfilled); - table.insert(self._pending_on_rejected, on_rejected); +local function wrap_handler(f, resolve, reject, default) + if not f then + return default; + end + return function (param) + local ok, ret = pcall(f, param); + if ok then + resolve(ret); + else + reject(ret); + end + return true; + end; end -local function next_fulfilled(promise, on_fulfilled, on_rejected) -- luacheck: ignore 212/on_rejected - on_fulfilled(promise.value); +local function next_pending(self, on_fulfilled, on_rejected, resolve, reject) + table.insert(self._pending_on_fulfilled, wrap_handler(on_fulfilled, resolve, reject, resolve)); + table.insert(self._pending_on_rejected, wrap_handler(on_rejected, resolve, reject, reject)); end -local function next_rejected(promise, on_fulfilled, on_rejected) -- luacheck: ignore 212/on_fulfilled - on_rejected(promise.reason); +local function next_fulfilled(promise, on_fulfilled, on_rejected, resolve, reject) -- luacheck: ignore 212/on_rejected + wrap_handler(on_fulfilled, resolve, reject)(promise.value); +end + +local function next_rejected(promise, on_fulfilled, on_rejected, resolve, reject) -- luacheck: ignore 212/on_fulfilled + wrap_handler(on_rejected, resolve, reject)(promise.reason); end local function promise_settle(promise, new_state, new_next, cbs, value) @@ -59,17 +74,6 @@ return _resolve, _reject; end -local function wrap_handler(f, resolve, reject) - return function (param) - local ok, ret = pcall(f, param); - if ok then - resolve(ret); - else - reject(ret); - end - end; -end - local function new(f) local p = setmetatable({ _state = "pending", _next = next_pending, _pending_on_fulfilled = {}, _pending_on_rejected = {} }, promise_mt); if f then @@ -123,10 +127,7 @@ function promise_methods:next(on_fulfilled, on_rejected) return new(function (resolve, reject) --luacheck: ignore 431/resolve 431/reject - self:_next( - on_fulfilled and wrap_handler(on_fulfilled, resolve, reject) or nil, - on_rejected and wrap_handler(on_rejected, resolve, reject) or nil - ); + self:_next(on_fulfilled, on_rejected, resolve, reject); end); end