mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-04 13:03:59 +01:00
Somewhat working version of promise_tech
Now with tests in a block comment at the bottom!
This commit is contained in:
parent
6bc27972b0
commit
2c36ad600a
@ -20,6 +20,7 @@ Promise.new = function(fn)
|
|||||||
|
|
||||||
local result = {
|
local result = {
|
||||||
state = "pending",
|
state = "pending",
|
||||||
|
force_reject = false,
|
||||||
fn = fn
|
fn = fn
|
||||||
}
|
}
|
||||||
setmetatable(result, Promise)
|
setmetatable(result, Promise)
|
||||||
@ -34,17 +35,22 @@ end
|
|||||||
*************************
|
*************************
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
--- A dummy function
|
||||||
|
local f = function(val) end
|
||||||
|
|
||||||
--- Then function for promises
|
--- Then function for promises
|
||||||
-- @param onFulfilled <function>: The function to call if the promise is fulfilled
|
-- @param onFulfilled <function>: The function to call if the promise is fulfilled
|
||||||
-- @param onRejected <function>: The function to call if the promise is rejected
|
-- @param onRejected <function>: The function to call if the promise is rejected
|
||||||
-- @return A promise object
|
-- @return A promise object containing a table of results
|
||||||
Promise.then_ = function(self, onFulfilled, onRejected)
|
Promise.then_ = function(self, onFulfilled, onRejected)
|
||||||
-- onFulfilled must be a function
|
-- onFulfilled must be a function or nil
|
||||||
if type(onFulfilled) ~= "function" and onRejected ~= nil then
|
if onFulfilled == nil then onFulfilled = f
|
||||||
|
elseif type(onFulfilled) ~= "function" then
|
||||||
error("Error (Promise.then_): First argument (onFulfilled) must be a function or nil")
|
error("Error (Promise.then_): First argument (onFulfilled) must be a function or nil")
|
||||||
end
|
end
|
||||||
-- onRejected must be a function or nil
|
-- onRejected must be a function or nil
|
||||||
if type(onRejected) ~= "function" and onRejected ~= nil then
|
if onRejected == nil then onRejected = f
|
||||||
|
elseif type(onRejected) ~= "function" then
|
||||||
error("Error (Promise.then_): Second argument (onRejected) must be a function or nil")
|
error("Error (Promise.then_): Second argument (onRejected) must be a function or nil")
|
||||||
end
|
end
|
||||||
-- If self.state is not "pending" then error
|
-- If self.state is not "pending" then error
|
||||||
@ -52,20 +58,27 @@ Promise.then_ = function(self, onFulfilled, onRejected)
|
|||||||
error("Error (Promise.then_): Promise is already " .. self.state)
|
error("Error (Promise.then_): Promise is already " .. self.state)
|
||||||
end
|
end
|
||||||
|
|
||||||
local result = function()
|
-- Make locals to collect the results of self.fn
|
||||||
local success, value = pcall(self.fn, onFulfilled, onRejected)
|
local result, force_reject = {nil}, self.force_reject
|
||||||
return Promise.new(function(resolve, reject)
|
|
||||||
if success then
|
-- Local resolve and reject functions
|
||||||
resolve(value)
|
local _resolve = function(value) result[1] = value end
|
||||||
self.state = "fulfilled"
|
local _reject = function(value)
|
||||||
else
|
result[1] = value
|
||||||
reject(value)
|
force_reject = true
|
||||||
self.state = "rejected"
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return result()
|
-- Call self.fn
|
||||||
|
local success, err = pcall(self.fn, _resolve, _reject)
|
||||||
|
|
||||||
|
-- Return a new promise with the results
|
||||||
|
if success and not force_reject then
|
||||||
|
onFulfilled(result[1])
|
||||||
|
return Promise.resolve(result[1])
|
||||||
|
else
|
||||||
|
onRejected(result[1])
|
||||||
|
return Promise.reject(success and result[1] or err)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Catch function for promises
|
--- Catch function for promises
|
||||||
@ -107,9 +120,50 @@ end
|
|||||||
-- @param value <any>: The value to reject the promise with
|
-- @param value <any>: The value to reject the promise with
|
||||||
-- @return A promise object
|
-- @return A promise object
|
||||||
Promise.reject = function(value)
|
Promise.reject = function(value)
|
||||||
return Promise.new(function(resolve, reject)
|
local promise = Promise.new(function(resolve, reject)
|
||||||
reject(value)
|
reject(value)
|
||||||
end)
|
end)
|
||||||
|
promise.force_reject = true
|
||||||
|
return promise
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Implement static methods (all, any, race etc.)
|
-- TODO: Implement static methods (all, any, race etc.)
|
||||||
|
|
||||||
|
|
||||||
|
return Promise
|
||||||
|
|
||||||
|
--- TESTS
|
||||||
|
--[[
|
||||||
|
Promise = require "promise_tech"
|
||||||
|
|
||||||
|
tmp = Promise.resolve(5)
|
||||||
|
tmp:then_(print, nil)
|
||||||
|
|
||||||
|
tmp = Promise.reject(7)
|
||||||
|
tmp:then_(nil, print)
|
||||||
|
|
||||||
|
--- BIG TESTS
|
||||||
|
|
||||||
|
function test()
|
||||||
|
return Promise.new(function(resolve, reject)
|
||||||
|
local value = math.random() -- imagine this was async
|
||||||
|
if value > 0.5 then
|
||||||
|
reject(value)
|
||||||
|
else
|
||||||
|
resolve(value)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function do_if_passes(val)
|
||||||
|
print("I passed!")
|
||||||
|
print("My value was " .. tostring(val))
|
||||||
|
end
|
||||||
|
|
||||||
|
function do_if_fails(err)
|
||||||
|
print("I failed!")
|
||||||
|
print("My error was " .. tostring(err))
|
||||||
|
end
|
||||||
|
|
||||||
|
test():then_(do_if_passes, do_if_fails)
|
||||||
|
]]
|
Loading…
Reference in New Issue
Block a user