From 4829a421db6d1ff9d74cc6800ea97c53b529331c Mon Sep 17 00:00:00 2001 From: Eryn Lynn Date: Sat, 28 Sep 2019 01:33:06 -0400 Subject: [PATCH] Add Promise:tap --- lib/README.md | 21 +++++++++++++++++++++ lib/init.lua | 19 +++++++++++++++++++ lib/init.spec.lua | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/lib/README.md b/lib/README.md index a86da21..cae404b 100644 --- a/lib/README.md +++ b/lib/README.md @@ -246,6 +246,27 @@ docs: params: "...: ...any?" returns: Promise returns: Promise + + - name: tap + desc: | + Similar to [[Promise.andThen]], except the return value is the same as the value passed to the handler. In other words, you can insert a `:tap` into a Promise chain without affecting the value that downstream Promises receive. + + ```lua + getTheValue() + :tap(print) + :andThen(function(theValue) + print("Got", theValue, "even though print returns nil!") + end) + ``` + + If you return a Promise from the tap handler callback, its value will be discarded but `tap` will still wait until it resolves before passing the original value through. + params: + - name: tapHandler + type: + kind: function + params: "...: ...any?" + returns: ...any? + returns: Promise<...any?> - name: finally desc: | diff --git a/lib/init.lua b/lib/init.lua index b0c5235..12a5546 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -401,6 +401,25 @@ function Promise.prototype:catch(failureCallback) return self:andThen(nil, failureCallback) end +--[[ + Like andThen, but the value passed into the handler is also the + value returned from the handler. +]] +function Promise.prototype:tap(tapCallback) + return self:andThen(function(...) + local callbackReturn = tapCallback(...) + + if Promise.is(callbackReturn) then + local length, values = pack(...) + return callbackReturn:andThen(function() + return unpack(values, 1, length) + end) + end + + return ... + end) +end + --[[ Calls a callback on `andThen` with specific arguments. ]] diff --git a/lib/init.spec.lua b/lib/init.spec.lua index c9accd9..36611c1 100644 --- a/lib/init.spec.lua +++ b/lib/init.spec.lua @@ -617,4 +617,47 @@ return function() expect(result).to.equal(2) end) end) + + describe("Promise.tap", function() + it("should thread through values", function() + local first, second + + Promise.resolve(1) + :andThen(function(v) + return v + 1 + end) + :tap(function(v) + first = v + return v + 1 + end) + :andThen(function(v) + second = v + end) + + expect(first).to.equal(2) + expect(second).to.equal(2) + end) + + it("should chain onto promises", function() + local resolveInner, finalValue + + local promise = Promise.resolve(1) + :tap(function() + return Promise.new(function(resolve) + resolveInner = resolve + end) + end) + :andThen(function(v) + finalValue = v + end) + + expect(promise:getStatus()).to.equal(Promise.Status.Started) + expect(finalValue).to.never.be.ok() + + resolveInner(1) + + expect(promise:getStatus()).to.equal(Promise.Status.Resolved) + expect(finalValue).to.equal(1) + end) + end) end \ No newline at end of file