Typesafe Promise implementation for Roblox Luau
Find a file
howmanysmall dde1c6517e
Update init.lua
- [Prefer calling string functions directly](https://developer.roblox.com/en-us/resources/release-note/Release-Notes-for-433)
- Fixed spaces being used in `Promise.retry`.
- Fixed `Promise:done` calling itself `Promise:finallyO` in the assert. (intentional?)
- Prefer using the first return of `ipairs` to add a Promise to the array instead of `table.insert`.
- Removed the unused `reject` in `Promise._try`
- Trailing commas as per Roblox Lua style guide.

Other suggestions:

- You could use `table.create` in `Promise:timeout` like so:

```Lua
function Promise.prototype:timeout(seconds, rejectionValue)
	local traceback = debug.traceback(nil, 2)

	local racedPromises = table.create(2)
	racedPromises[1] = Promise.delay(seconds):andThen(function()
		return Promise.reject(rejectionValue == nil and Error.new({
			kind = Error.Kind.TimedOut,
			error = "Timed out",
			context = string.format(
				"Timeout of %d seconds exceeded.\n:timeout() called at:\n\n%s",
				seconds,
				traceback
			),
		}) or rejectionValue)
	end)

	racedPromises[2] = self
	return Promise.race(racedPromises)
end
```
2020-06-09 12:53:06 -06:00
.github Create FUNDING.yml 2020-04-24 17:51:14 -04:00
.vuepress Update docs 2020-06-02 00:54:36 -04:00
lib Update init.lua 2020-06-09 12:53:06 -06:00
modules Update testez 2020-05-04 22:07:55 -04:00
.editorconfig Initial dump 2018-01-25 17:21:58 -08:00
.gitignore Update for release 2019-09-10 15:34:06 -04:00
.gitmodules Remove unused files 2020-05-04 22:07:36 -04:00
.luacheckrc Start implementing tests, add lemur and testez dependencies 2018-01-31 15:29:04 -08:00
CHANGELOG.md Update docs 2020-06-02 00:54:36 -04:00
default.project.json Update testez 2020-05-04 22:07:55 -04:00
LICENSE Update LICENSE 2019-09-10 00:29:21 -04:00
package-lock.json Merge branch 'master' into use-xpcall 2020-05-05 18:15:45 -04:00
package.json Merge branch 'master' into use-xpcall 2020-05-05 18:15:45 -04:00
README.md Update README.md 2020-06-02 01:00:03 -04:00
rotriever.toml Update docs 2020-06-02 00:54:36 -04:00
runTests.server.lua Update testez 2020-05-04 22:07:55 -04:00

Roblox Lua Promise

An implementation of Promise similar to Promise/A+.

View docs

Why you should use Promises

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:

  • An object that represents a unit of asynchronous work
  • Composability
  • Predictable timing

Example

Promise.new returns synchronously.

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)
	return Promise.new(function(resolve, reject)
		local ok, result = pcall(HttpService.GetAsync, HttpService, url)

		if ok then
			resolve(result)
		else
			reject(result)
		end
	end)
end

-- Usage
httpGet("https://google.com")
	:andThen(function(body)
		print("Here's the Google homepage:", body)
	end)
	:catch(function(err)
		warn("We failed to get the Google homepage!", err)
	end)