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
46 assert(any_child, "Uncaught (in promise): " .. reason)
49 function PromisePrototype:then_(on_resolve, on_reject)
50 local promise = Promise()
51 promise.__on_resolve = on_resolve
52 promise.__on_reject = on_reject
54 self:__add_child(promise)
59 function PromisePrototype:catch(func)
60 local promise = Promise(function() end)
61 promise.__on_reject = func
63 self:__add_child(promise)
68 function PromisePrototype:resolve(...)
69 assert(self.state == "pending")
71 if self.__on_resolve then
72 self:__run_handler(self.__on_resolve, ...)
74 self:__resolve_raw(...)
78 function PromisePrototype:reject(reason)
79 assert(self.state == "pending")
81 if self.__on_reject then
82 self:__run_handler(self.__on_reject, reason)
84 self:__reject_raw(reason)
88 Promise = setmetatable({}, {
89 __call = function(_, resolver)
90 local promise = setmetatable({
93 }, {__index = PromisePrototype})
110 function Promise.resolve(...)
112 return Promise(function(resolve)
113 resolve(unpack(args))