1 local PromisePrototype = {}
3 function PromisePrototype:__run_handler(func, ...)
4 local values = {pcall(func, ...)}
6 if table.remove(values, 1) then
7 self:__resolve_raw(unpack(values))
9 self:__reject_raw(values[1])
13 function PromisePrototype:__add_child(promise)
14 if self.state == "resolved" then
15 promise:__resolve(unpack(self.values))
16 elseif self.state == "rejected" then
17 promise:__reject(self.reason)
19 table.insert(self.__children, promise)
23 function PromisePrototype:__resolve_raw(...)
24 self.state = "resolved"
28 for _, child in ipairs(self.__children) do
33 function PromisePrototype:__reject_raw(reason)
34 self.state = "rejected"
38 local any_child = false
40 for _, child in ipairs(self.__children) do
44 assert(any_child, "Uncaught (in promise): " .. reason)
47 function PromisePrototype:resolve(...)
48 assert(self.state == "pending")
50 if self.__on_resolve then
51 self:__run_handler(self.__on_resolve, ...)
53 self:__resolve_raw(...)
57 function PromisePrototype:reject(reason)
58 assert(self.state == "pending")
60 if self.__on_reject then
61 self:__run_handler(self.__on_reject, reason)
63 self:__reject_raw(reason)
67 function PromisePrototype:then_(func)
68 local promise = Promise()
69 promise.__on_resolve = func
71 self:__add_child(promise)
76 function PromisePrototype:catch(func)
77 local promise = Promise(function() end)
78 promise.__on_reject = func
80 self:__add_child(promise)
85 Promise = setmetatable({}, {
86 __call = function(_, resolver)
92 setmetatable(promise, {__index = PromisePrototype})
109 function Promise.resolve(...)
111 return Promise(function(resolve)
112 resolve(unpack(args))