luau-promise/README.md

53 lines
2 KiB
Markdown
Raw Normal View History

2019-09-10 19:44:48 +00:00
<div align="center">
<h1>Roblox Lua Promise</h1>
<p>An implementation of <code>Promise</code> similar to Promise/A+.</p>
<a href="https://eryn.io/roblox-lua-promise/"><strong>View docs</strong></a>
</div>
2018-04-11 22:26:54 +00:00
2019-09-12 08:00:39 +00:00
## Why you should use Promises
2018-04-11 22:26:54 +00:00
2019-09-10 19:34:06 +00:00
The way Roblox models asynchronous operations by default is by yielding (stopping) the thread and then resuming it when the future value is available. This model is not ideal because:
- Functions you call can yield without warning, or only yield sometimes, leading to unpredictable and surprising results. Accidentally yielding the thread is the source of a large class of bugs and race conditions that Roblox developers run into.
- It is difficult to deal with running multiple asynchronous operations concurrently and then retrieve all of their values at the end without extraneous machinery.
- When an asynchronous operation fails or an error is encountered, Lua functions usually either raise an error or return a success value followed by the actual value. Both of these methods lead to repeating the same tired patterns many times over for checking if the operation was successful.
- Yielding lacks easy access to introspection and the ability to cancel an operation if the value is no longer needed.
This Promise implementation attempts to satisfy these traits:
2018-04-11 22:26:54 +00:00
* An object that represents a unit of asynchronous work
* Composability
* Predictable timing
## Example
2020-06-02 05:00:03 +00:00
`Promise.new` returns synchronously.
2018-04-11 22:26:54 +00:00
```lua
local HttpService = game:GetService("HttpService")
-- A light wrapper around HttpService
-- Ideally, you do this once per project per async method that you use.
local function httpGet(url)
2020-06-02 05:00:03 +00:00
return Promise.new(function(resolve, reject)
2020-08-17 23:31:08 +00:00
local result = HttpService:JSONDecode(HttpService:GetAsync(url))
2019-09-10 21:14:24 +00:00
2020-08-17 23:31:08 +00:00
if result.ok then
resolve(result.data)
2019-09-10 21:14:24 +00:00
else
2020-08-17 23:31:08 +00:00
reject(result.error)
2019-09-10 21:14:24 +00:00
end
2018-04-11 22:26:54 +00:00
end)
end
-- Usage
2020-08-17 23:31:08 +00:00
httpGet("https://some-api.example")
2018-04-11 22:26:54 +00:00
:andThen(function(body)
2020-08-17 23:31:08 +00:00
print("Here's the web api result:", body)
2018-04-11 22:26:54 +00:00
end)
:catch(function(err)
2020-08-17 23:31:08 +00:00
warn("Web api encountered an error:", err)
2018-04-11 22:26:54 +00:00
end)
```
2020-08-17 23:31:08 +00:00