1 local unpack = unpack or table.unpack
2 local PromisePrototype = {}
4 function PromisePrototype:__run_handler(func, ...)
5 local values = {pcall(func, ...)}
7 if table.remove(values, 1) then
8 self:__resolve_raw(unpack(values))
10 self:__reject_raw(values[1])
14 function PromisePrototype:__add_child(promise)
15 if self.state == "resolved" then
16 promise:__resolve(unpack(self.values))
17 elseif self.state == "rejected" then
18 promise:__reject(self.reason)
20 table.insert(self.__children, promise)
24 function PromisePrototype:__resolve_raw(...)
25 self.state = "resolved"
29 for _, child in ipairs(self.__children) do
34 function PromisePrototype:__reject_raw(reason)
35 self.state = "rejected"
39 local any_child = false
41 for _, child in ipairs(self.__children) do
45 assert(any_child, "Uncaught (in promise): " .. reason)
48 function PromisePrototype:then_(on_resolve, on_reject)
49 local promise = Promise()
50 promise.__on_resolve = on_resolve
51 promise.__on_reject = on_reject
53 self:__add_child(promise)
58 function PromisePrototype:catch(func)
59 local promise = Promise(function() end)
60 promise.__on_reject = func
62 self:__add_child(promise)
67 function PromisePrototype:resolve(...)
68 assert(self.state == "pending")
70 if self.__on_resolve then
71 self:__run_handler(self.__on_resolve, ...)
73 self:__resolve_raw(...)
77 function PromisePrototype:reject(reason)
78 assert(self.state == "pending")
80 if self.__on_reject then
81 self:__run_handler(self.__on_reject, reason)
83 self:__reject_raw(reason)
87 Promise = setmetatable({}, {
88 __call = function(_, resolver)
89 local promise = setmetatable({
92 }, {__index = PromisePrototype})
109 function Promise.resolve(...)
111 return Promise(function(resolve)
112 resolve(unpack(args))