Skip to content
Promise implementation for Roblox
Lua JavaScript
Branch: master
Clone or download
Latest commit 4daaf7e Oct 1, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vuepress Make cancellation propagate downstream Sep 12, 2019
lib Update done docs Oct 1, 2019
modules Start implementing tests, add lemur and testez dependencies Jan 31, 2018
.editorconfig Initial dump Jan 26, 2018
.gitignore Update for release Sep 10, 2019
.gitmodules Start implementing tests, add lemur and testez dependencies Jan 31, 2018
.luacheckrc Start implementing tests, add lemur and testez dependencies Jan 31, 2018
.luacov Add .gitignore and .luacov Feb 1, 2018
CHANGELOG.md
LICENSE Update LICENSE Sep 10, 2019
README.md Update README.md Sep 12, 2019
default.project.json Update for release Sep 10, 2019
package-lock.json Make cancellation propagate downstream Sep 12, 2019
package.json Make cancellation propagate downstream Sep 12, 2019
rotriever.toml Make all/race cancel correctly Sep 28, 2019
spec.lua Start implementing tests, add lemur and testez dependencies Jan 31, 2018

README.md

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.async 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.async(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)
You can’t perform that action at this time.