An alternative to Promises, inspired by Fluture
THIS DOCUMENT IS OUTDATED
Importing with Neon:
Future = NEON:github('belkworks', 'future')
When a Future is executed, the runner is passed two functions, reject
and resolve
.
Calling reject
or resolve
(with an output as an optional argument) will settle the Future.
Futures can only be settled once, so additional calls to reject
/resolve
will be ignored.
Future(runner) -> Future
F = Future(function(reject, resolve)
coroutine.wrap(function() -- do some (a)synchronous work
resolve(123) -- resolve with the value 123
-- reject(456) -- reject with the value 456
-- resolve() -- resolve with no value
-- reject() -- reject with no value
end)()
return function() end -- return a cancel function
end)
Alternatively, you can use a node-style runner by calling the node
function.
The runner is passed a single function, done
, that settles the Future.
node(nodeback) -> Future
node = Future.node
F = node(function(done)
coroutine.wrap(function() -- do some (a)synchronous work
done(nil, 123) -- resolve with value 123
-- done(123) or done(123, nil) -- reject with value 123
-- done() -- resolve with no value
end)()
-- No cancel function, return is ignored
end)
You can make a Future that instantly resolves using the resolve
function.
resolve = Future.resolve
F = resolve(42)
Similarly, you can use the reject
function to make a Future that instantly rejects.
reject = Future.reject
F = reject(-4)
In the following examples, F
is a Future.
To run a Future, use the fork
function.
fork(future, reject, resolve) -> Cancel
fork = Future.fork
cancel = fork(F, warn, function(v)
print('resolved with:', v)
end)
-- call cancel to unsubscribe from the execution
-- cancel()
If a Future is sure to succeed, You can use the value
function.
This function will throw if the Future is rejected.
value(future, resolve) -> Cancel
value = Future.value
cancel = value(F, function(v)
print('resolved with:', v)
end)
You can run a Future using the node style with the done
function.
The callback will receive two parameters - e
and v
.
If e
is nil, the Future resolved with the value v
.
Otherwise it rejected with the value e
.
done(future, fn) -> Cancel
done = Future.done
cancel = done(F, function(e, v)
if e == nil then
print('resolved with:', v)
else
print('rejected with:', e)
end
end)
Every Future has a pipe
method to allow fluent chaining of futures.
The receiving function, in this case map
, should take a Future as its first argument.
Future:pipe(fn, ...) -> Future
resolve = Future.resolve
map = Future.map
value = Future.value
num = resolve(42)
doubled = num:pipe(map, function(v) return v*2 end)
value(doubled, print) -- prints 84