Software /
code /
prosody
Changeset
10922:7d3dbb9eb3eb
util.promise: Add all_settled, which follows semantics of allSettled from ES2020
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 08 Jun 2020 14:01:02 +0100 |
parents | 10921:6eb5d2bb11af |
children | 10923:dff1aebd0f2b |
files | spec/util_promise_spec.lua util/promise.lua |
diffstat | 2 files changed, 76 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/spec/util_promise_spec.lua Sun Jun 07 02:25:56 2020 +0200 +++ b/spec/util_promise_spec.lua Mon Jun 08 14:01:02 2020 +0100 @@ -353,6 +353,60 @@ assert.equal("fail", result); end); end); + describe("all_settled()", function () + it("works with fulfilled promises", function () + local p1, p2 = promise.resolve("yep"), promise.resolve("nope"); + local p = promise.all_settled({ p1, p2 }); + local result; + p:next(function (v) + result = v; + end); + assert.same({ + { status = "fulfilled", value = "yep" }; + { status = "fulfilled", value = "nope" }; + }, result); + end); + it("works with pending promises", function () + local r1, r2; + local p1, p2 = promise.new(function (resolve) r1 = resolve end), promise.new(function (resolve) r2 = resolve end); + local p = promise.all_settled({ p1, p2 }); + + local result; + local cb = spy.new(function (v) + result = v; + end); + p:next(cb); + assert.spy(cb).was_called(0); + r2("yep"); + assert.spy(cb).was_called(0); + r1("nope"); + assert.spy(cb).was_called(1); + assert.same({ + { status = "fulfilled", value = "nope" }; + { status = "fulfilled", value = "yep" }; + }, result); + end); + it("works when some promises reject", function () + local r1, r2; + local p1, p2 = promise.new(function (resolve) r1 = resolve end), promise.new(function (_, reject) r2 = reject end); + local p = promise.all_settled({ p1, p2 }); + + local result; + local cb = spy.new(function (v) + result = v; + end); + p:next(cb); + assert.spy(cb).was_called(0); + r2("this fails"); + assert.spy(cb).was_called(0); + r1("this succeeds"); + assert.spy(cb).was_called(1); + assert.same({ + { status = "fulfilled", value = "this succeeds" }; + { status = "rejected", reason = "this fails" }; + }, result); + end); + end); describe("catch()", function () it("works", function () local result;
--- a/util/promise.lua Sun Jun 07 02:25:56 2020 +0200 +++ b/util/promise.lua Mon Jun 08 14:01:02 2020 +0100 @@ -104,6 +104,27 @@ end); end +local function all_settled(promises) + return new(function (resolve) + local count, total, results = 0, #promises, {}; + for i = 1, total do + promises[i]:next(function (v) + results[i] = { status = "fulfilled", value = v }; + count = count + 1; + if count == total then + resolve(results); + end + end, function (e) + results[i] = { status = "rejected", reason = e }; + count = count + 1; + if count == total then + resolve(results); + end + end); + end + end); +end + local function race(promises) return new(function (resolve, reject) for i = 1, #promises do @@ -149,6 +170,7 @@ resolve = resolve; reject = reject; all = all; + all_settled = all_settled; race = race; try = try; is_promise = is_promise;