]> git.lizzy.rs Git - lua_async.git/blob - promises.lua
Fix some small mistakes in the documentation of clearImmediate
[lua_async.git] / promises.lua
1 local PromisePrototype = {}
2
3 function PromisePrototype:__run_handler(func, ...)
4         local values = {pcall(func, ...)}
5
6         if table.remove(values, 1) then
7                 self:__resolve_raw(unpack(values))
8         else
9                 self:__reject_raw(values[1])
10         end
11 end
12
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)
18         else
19                 table.insert(self.__children, promise)
20         end
21 end
22
23 function PromisePrototype:__resolve_raw(...)
24         self.state = "resolved"
25         self.values = {...}
26         self.reason = nil
27
28         for _, child in ipairs(self.__children) do
29                 child:resolve(...)
30         end
31 end
32
33 function PromisePrototype:__reject_raw(reason)
34         self.state = "rejected"
35         self.values = nil
36         self.reason = reason
37
38         local any_child = false
39
40         for _, child in ipairs(self.__children) do
41                 child:reject(reason)
42         end
43
44         assert(any_child, "Uncaught (in promise): " .. reason)
45 end
46
47 function PromisePrototype:resolve(...)
48         assert(self.state == "pending")
49
50         if self.__on_resolve then
51                 self:__run_handler(self.__on_resolve, ...)
52         else
53                 self:__resolve_raw(...)
54         end
55 end
56
57 function PromisePrototype:reject(reason)
58         assert(self.state == "pending")
59
60         if self.__on_reject then
61                 self:__run_handler(self.__on_reject, reason)
62         else
63                 self:__reject_raw(reason)
64         end
65 end
66
67 function PromisePrototype:then_(func)
68         local promise = Promise()
69         promise.__on_resolve = func
70
71         self:__add_child(promise)
72
73         return promise
74 end
75
76 function PromisePrototype:catch(func)
77         local promise = Promise(function() end)
78         promise.__on_reject = func
79
80         self:__add_child(promise)
81
82         return promise
83 end
84
85 Promise = setmetatable({}, {
86         __call = function(_, resolver)
87                 local promise = {
88                         state = "pending",
89                         __children = {},
90                 }
91
92                 setmetatable(promise, {__index = PromisePrototype})
93
94                 if resolver then
95                         resolver(
96                                 function(...)
97                                         promise:resolve(...)
98                                 end,
99                                 function(...)
100                                         promise:reject(...)
101                                 end
102                         )
103                 end
104
105                 return promise
106         end
107 })
108
109 function Promise.resolve(...)
110         local args = {...}
111         return Promise(function(resolve)
112                 resolve(unpack(args))
113         end)
114 end