Promise

A value that arrives later: one thread settles it, and any number of others wait for it, each with its own timeout.

Make one with Promise.new() and settle it once with SetValue or Fail, or let Promise.Spawn(work, ...) run work in a new thread and settle with its first result. false and nil are real values, so Settled says whether it has one. Promise.AllAsync waits for a whole list, and settling twice is an error.

Example

A value arriving laterLuau
--!strict
-- An order that arrives later: one thread settles it, the program waits for it.
local Promise = require("@shotsystem/Promise")
local TimeService = require("@shotsystem/TimeService")

local order = Promise.new()
order.Done:Connect(function(value : any, why : string?)
	print("Done fired with:", value, why)
end)
Promise.Spawn(function()
	TimeService:WaitAsync(0.1)
	order:SetValue("Apple")
end)
print("before:", order.Settled, tostring(order))
print("arrived:", order:GetValueAsync(5))
print("after:", order.Settled, order.Value, tostring(order))
-- false is a real value, a wait can time out, and a failure comes back as why
local empty = Promise.new()
empty:SetValue(false)
print("false:", empty:GetValueAsync())
print("never settled:", Promise.new():GetValueAsync(0.1))
local sold = Promise.new()
sold:Fail("out of stock")
print("failed:", sold:GetValueAsync())

-- Spawn runs a function in a thread of its own; AllAsync waits for them all
local price = Promise.Spawn(function(count : number) return count * 3 end, 4)
local shop = Promise.Spawn(function() return "Shop" end)
local values = Promise.AllAsync({ price, shop })
print("all:", values and values[1], values and values[2], Promise.Is(price), Promise.Is({}))
What it printedOutput
before: false Promise(pending)
Done fired with: Apple nil
arrived: Apple nil
after: true Apple Promise(Apple)
false: false nil
never settled: nil timed out
failed: nil out of stock
all: 12 Shop true false

Constructors

NameArgumentsReturnsDescription
Promise.new()PromiseA pending Promise, for one thread to settle and any number to wait on.
Promise.Spawn(work: (...any) -> ...any, ...any)PromiseRuns work(...) in a new thread; the Promise settles with its first result only, or fails with its error's message.
Promise.AllAsync(promises: { Promise }, timeout: number?)({ any }?, string?)Waits for every Promise: their values in order, or (nil, why) as soon as one fails or the timeout passes.
Promise.Is(value: any)booleanTrue for a Promise, since typeof can't tell a library datatype apart.

Properties

NameTypeDefaultDescription
SettledbooleanWhether it has a value or a failure yet, the only way to tell a nil or false value from none.
ValueanyThe value once settled, nil before and after a failure; it can't be set, settle with SetValue.
Errorstring?Why it failed, as given to Fail; nil until then and after SetValue.

Methods

NameArgumentsReturnsDescription
SetValue(value: any)()Settles it with value, which may be nil or false; settling a Promise that is already settled is an error.
Fail(why: string)()Settles it as failed with why, which every waiter gets as its second result; settling twice is an error.
GetValueAsync
yields
(timeout: number?)(any, string?)Gives the value at once when settled, else waits for it: (value, nil), or (nil, why) on a failure or "timed out".

Events

NamePassesDescription
Done(any, string?)Fires when it settles, with (value, nil) or (nil, why); a connection made after settling hears nothing, so use GetValueAsync then.