From 774e9c62c5e4076c337f0ac29fddc5c51d9c8927 Mon Sep 17 00:00:00 2001 From: Eryn Lynn Date: Tue, 23 Oct 2018 19:12:05 -0400 Subject: [PATCH] Implement promise cancellation --- lib/init.lua | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/init.lua b/lib/init.lua index 3c8bc62..8f4a4bd 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -84,6 +84,7 @@ Promise.Status = { Started = createSymbol("Started"), Resolved = createSymbol("Resolved"), Rejected = createSymbol("Rejected"), + Cancelled = createSymbol("Cancelled"), } --[[ @@ -134,6 +135,9 @@ function Promise.new(callback) -- Queues representing functions we should invoke when we update! _queuedResolve = {}, _queuedReject = {}, + + -- The function to run when/if this promise is cancelled. + _cancellationHook = nil, } setmetatable(self, Promise) @@ -146,7 +150,11 @@ function Promise.new(callback) self:_reject(...) 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 err = result[2] @@ -290,6 +298,22 @@ function Promise.prototype:catch(failureCallback) return self:andThen(nil, failureCallback) 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.