Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/promise.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ local newPromise
local resolve
local promiseOnFulfilled
local promiseOnRejected
local onUnhandledPromiseRejection

local function isPromise(x)
if type(x) ~= 'table' then return false end
Expand Down Expand Up @@ -109,6 +110,7 @@ promiseOnRejected = function (p, reason)
p._value = nil
p._reason = reason
p._state = REJECTED
p._rejectHandled = #p.thenInfoList > 0
end
for _,n in ipairs(p.thenInfoList) do
execRejected(n, reason)
Expand Down Expand Up @@ -170,6 +172,14 @@ function promise:new()
p._state = PENDING
p._value = nil
p._reason = nil
p._rejectHandled = nil

if newproxy then
-- With lua <= 5.1 and luajit, __gc is not called on table.
local proxy = newproxy(true)
getmetatable(proxy).__gc = function() p:__gc() end
p[proxy] = true
end

return p
end
Expand All @@ -192,6 +202,7 @@ function promise:thenCall(onFulfilled, onRejected)
if self._state == FULFILLED then
execFulfilled(thenInfo, self._value)
elseif self._state == REJECTED then
self._rejectHandled = isCallable(onRejected)
execRejected(thenInfo, self._reason)
end

Expand All @@ -204,6 +215,14 @@ function promise:catch(onRejected)
return self:thenCall(nil, onRejected)
end

function promise:__gc()
if self._state == REJECTED and not self._rejectHandled then
if isCallable(onUnhandledPromiseRejection) then
onUnhandledPromiseRejection(self._reason)
end
end
end

newPromise = function (func)
local obj = promise:new()
local isCalled = false
Expand Down Expand Up @@ -391,4 +410,8 @@ function Promise.serial(array)
end)
end

function Promise.onUnhandledPromiseRejection(cb)
onUnhandledPromiseRejection = cb
end

return Promise