Somewhat related to #59. Right now, finally acts as a consumer of the root promise. This means if another consumer of the root promise (that is, a sibling of the finally promise) is cancelled, the root itself will not be cancelled because it still has a second consumer (the finally promise itself).
If we make it so that finally forwards rejection values and doesn't reset the state (#59), then we should probably also make it so that finally does not count as a proper consumer. This way attaching a finally to a chain is more or less transparent and doesn't affect the logistics of cancellation.
An example where this causes problems:
local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))
local Promise = require("Promise")
local function wrapPromise(x)
return Promise.resolve(x)
end
local test = function()
-- 'a' always has the state 'Started'.
local a = Promise.delay(2)
a:finally(function()
print("Test - this should be called on cancel.")
end)
return a
end
local prom = test()
wait()
prom:cancel() -- This will print 'test' to the console immediately.
local prom2 = wrapPromise(test())
wait()
prom2:cancel() -- This will print 'test' to the console after **2 seconds**, as the promise can't be cancelled.
Somewhat related to #59. Right now,
finally
acts as a consumer of the root promise. This means if another consumer of the root promise (that is, a sibling of thefinally
promise) is cancelled, the root itself will not be cancelled because it still has a second consumer (thefinally
promise itself).If we make it so that
finally
forwards rejection values and doesn't reset the state (#59), then we should probably also make it so thatfinally
does not count as a proper consumer. This way attaching afinally
to a chain is more or less transparent and doesn't affect the logistics of cancellation.An example where this causes problems: