Implement promise cancellation

This commit is contained in:
Eryn Lynn 2018-10-23 19:12:05 -04:00
parent 3b30a3fa70
commit 774e9c62c5

View file

@ -84,6 +84,7 @@ Promise.Status = {
Started = createSymbol("Started"), Started = createSymbol("Started"),
Resolved = createSymbol("Resolved"), Resolved = createSymbol("Resolved"),
Rejected = createSymbol("Rejected"), Rejected = createSymbol("Rejected"),
Cancelled = createSymbol("Cancelled"),
} }
--[[ --[[
@ -134,6 +135,9 @@ function Promise.new(callback)
-- Queues representing functions we should invoke when we update! -- Queues representing functions we should invoke when we update!
_queuedResolve = {}, _queuedResolve = {},
_queuedReject = {}, _queuedReject = {},
-- The function to run when/if this promise is cancelled.
_cancellationHook = nil,
} }
setmetatable(self, Promise) setmetatable(self, Promise)
@ -146,7 +150,11 @@ function Promise.new(callback)
self:_reject(...) self:_reject(...)
end end
local _, result = wpcallPacked(callback, resolve, reject) local function onCancel(cancellationHook)
self._cancellationHook = cancellationHook
end
local _, result = wpcallPacked(callback, resolve, reject, onCancel)
local ok = result[1] local ok = result[1]
local err = result[2] local err = result[2]
@ -290,6 +298,22 @@ function Promise.prototype:catch(failureCallback)
return self:andThen(nil, failureCallback) return self:andThen(nil, failureCallback)
end end
--[[
Cancels the promise, disallowing it from rejecting or resolving, and calls
the cancellation hook if provided.
]]
function Promise.prototype:cancel()
if self._status ~= Promise.Status.Started then
return
end
self._status = Promise.Status.Cancelled
if self._cancellationHook then
self._cancellationHook()
end
end
--[[ --[[
Yield until the promise is completed. Yield until the promise is completed.