Cancel finally returned promise if outer cancelled

This commit is contained in:
eryn L. K 2021-12-28 05:24:19 -05:00
parent afc245c4f1
commit 893c43a90c
2 changed files with 20 additions and 0 deletions

View file

@ -1436,11 +1436,17 @@ function Promise.prototype:_finally(traceback, finallyHandler)
self._unhandledRejection = false
local promise = Promise._new(traceback, function(resolve, reject, onCancel)
local handlerPromise
onCancel(function()
-- The finally Promise is not a proper consumer of self. We don't care about the resolved value.
-- All we care about is running at the end. Therefore, if self has no other consumers, it's safe to
-- cancel. We don't need to hold out cancelling just because there's a finally handler.
self:_consumerCancelled(self)
if handlerPromise then
handlerPromise:cancel()
end
end)
local finallyCallback = resolve
@ -1449,6 +1455,8 @@ function Promise.prototype:_finally(traceback, finallyHandler)
local callbackReturn = finallyHandler(...)
if Promise.is(callbackReturn) then
handlerPromise = callbackReturn
callbackReturn
:finally(function(status)
if status ~= Promise.Status.Rejected then

View file

@ -835,6 +835,18 @@ return function()
expect(finallyRan).to.equal(true)
expect(andThenRan).to.equal(false)
end)
it("should cancel returned promise if cancelled", function()
local internal = Promise.new(function() end)
local promise = Promise.resolve():finally(function()
return internal
end)
promise:cancel()
expect(internal:getStatus()).to.equal(Promise.Status.Cancelled)
end)
end)
describe("Promise.all", function()