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:then_(on_resolve, on_reject)
48 local promise = Promise()
49 promise.__on_resolve = on_resolve
50 promise.__on_reject = on_reject
52 self:__add_child(promise)
57 function PromisePrototype:catch(func)
58 local promise = Promise(function() end)
59 promise.__on_reject = func
61 self:__add_child(promise)
66 function PromisePrototype:resolve(...)
67 assert(self.state == "pending")
69 if self.__on_resolve then
70 self:__run_handler(self.__on_resolve, ...)
72 self:__resolve_raw(...)
76 function PromisePrototype:reject(reason)
77 assert(self.state == "pending")
79 if self.__on_reject then
80 self:__run_handler(self.__on_reject, reason)
82 self:__reject_raw(reason)
86 Promise = setmetatable({}, {
87 __call = function(_, resolver)
93 setmetatable(promise, {__index = PromisePrototype})
110 function Promise.resolve(...)
112 return Promise(function(resolve)
113 resolve(unpack(args))