Promise

A Promise is an object that represents a value that will exist in the future, but doesn't right now. Promises allow you to then attach callbacks that can run once the value becomes available (known as resolving), or if an error has occurred (known as rejecting).

Types

# PromiseStatus

enum PromiseStatus {
Started

The Promise is executing, and not settled yet.

Resolved

The Promise finished successfully.

Rejected

The Promise was rejected.

Cancelled

The Promise was cancelled before it finished.

}

An enum value used to represent the Promise's status.

Properties

# Status read onlystaticenums

Promise.Status: PromiseStatus

A table containing all members of the PromiseStatus enum, e.g., Promise.Status.Resolved.

Static Functions

# new constructorstatic

Promise.new(executor: function(

resolve: function(...?: ...any) → void,
reject: function(...?: ...any) → void,
onCancel: function(abortHandler: ) → boolean
) → ) → Promise

Construct a new Promise that will be resolved or rejected with the given callbacks.

If your Promise executor needs to yield, it is recommended to use Promise.async instead. You cannot directly yield inside the executor function of Promise.new.

If you resolve with a Promise, it will be chained onto.

You may register an optional cancellation hook by using the onCancel argument.

  • This should be used to abort any ongoing operations leading up to the promise being settled.
  • Call the onCancel function with a function callback as its only argument to set a hook which will in turn be called when/if the promise is cancelled.
  • onCancel returns true if the Promise was already cancelled when you called onCancel.
  • Calling onCancel with no argument will not override a previously set cancellation hook, but it will still return true if the Promise is currently cancelled.
  • You can set the cancellation hook at any time before resolving.
  • When a promise is cancelled, calls to resolve or reject will be ignored, regardless of if you set a cancellation hook or not.

Parameters

Name Type Required
executor

function(

resolve: function(...?: ...any) → void,
reject: function(...?: ...any) → void,
onCancel: function(abortHandler: ) → boolean
) →

Details

Parameters

Name Type Required
resolve

function(...?: ...any) → void

Details

Parameters

Name Type Required
... ...any

Returns

Type
void
reject

function(...?: ...any) → void

Details

Parameters

Name Type Required
... ...any

Returns

Type
void
onCancel

function(abortHandler: ) → boolean

Details

Parameters

Name Type Required
abortHandler

Returns

Type
boolean

Returns true if the Promise was already cancelled at the time of calling onCancel.

Returns

Type

Returns

Type
Promise

# async constructorstatic

Promise.async(asyncExecutor: function(

resolve: function(...?: ...any) → void,
reject: function(...?: ...any) → void,
onCancel: function(abortHandler: ) → boolean
) → ) → Promise

The same as Promise.new, except it allows yielding. Use this if you want to yield inside your Promise body.

If your Promise body does not need to yield, such as when attaching resolve to an event listener, you should use Promise.new instead.

Promises created with Promise.async don't begin executing until the next RunService.Heartbeat event, even if the executor function doesn't yield itself. This is to ensure that Promises produced from a function are either always synchronous or always asynchronous. Learn more

local function waitForChild(instance, childName, timeout)
  return Promise.async(function(resolve, reject)
    local child = instance:WaitForChild(childName, timeout)

    ;(child and resolve or reject)(child)
  end)
end

Parameters

Name Type Required
asyncExecutor

function(

resolve: function(...?: ...any) → void,
reject: function(...?: ...any) → void,
onCancel: function(abortHandler: ) → boolean
) →

Details

Parameters

Name Type Required
resolve

function(...?: ...any) → void

Details

Parameters

Name Type Required
... ...any

Returns

Type
void
reject

function(...?: ...any) → void

Details

Parameters

Name Type Required
... ...any

Returns

Type
void
onCancel

function(abortHandler: ) → boolean

Details

Parameters

Name Type Required
abortHandler

Returns

Type
boolean

Returns true if the Promise was already cancelled at the time of calling onCancel.

Returns

Type

Returns

Type
Promise

# promisify static

Promise.promisify(callback: function(...?: ...any) → ) → function(...?: ...any) →

Wraps a function that yields into one that returns a Promise.

Any errors that occur while executing the function will be turned into rejections.

local sleep = Promise.promisify(wait)

sleep(1):andThen(print)
local isPlayerInGroup = Promise.promisify(function(player, groupId)
  return player:IsInGroup(groupId)
end)

Parameters

Name Type Required
callback

function(...?: ...any) →

Details

Parameters

Name Type Required
... ...any

Returns

Type

Returns

Type

function(...?: ...any) →

Details

Parameters

Name Type Required
... ...any

The same arguments the wrapped function usually takes.

Returns

Type

The return values from the wrapped function.

The function acts like the passed function but now returns a Promise of its return values.

# resolve static

Promise.resolve(value: ...any) → Promise<...any>

Creates an immediately resolved Promise with the given value.

Parameters

Name Type Required
value ...any

Returns

Type
Promise<...any>

# reject static

Promise.reject(value: ...any) → Promise<...any>

Creates an immediately rejected Promise with the given value.

Parameters

Name Type Required
value ...any

Returns

Type
Promise<...any>

# try static

Promise.try(

callback: function(...?: ...any) → ...any,
...?: ...any
) → Promise<...any>

Begins a Promise chain, calling a synchronous function and returning a Promise resolving with its return value. If the function errors, the returned Promise will be rejected with the error.

Promise.try is similar to Promise.promisify, except the callback is invoked immediately instead of returning a new function, and unlike promisify, yielding is not allowed with try.

Promise.try(function()
  return math.random(1, 2) == 1 and "ok" or error("Oh an error!")
end)
  :andThen(function(text)
    print(text)
  end)
  :catch(function(err)
    warn("Something went wrong")
  end)

Parameters

Name Type Required
callback

function(...?: ...any) → ...any

Details

Parameters

Name Type Required
... ...any

Returns

Type
...any?
... ...any

Arguments for the callback

Returns

Type
Promise<...any?>

The return value of the passed callback.

# all static

Promise.all(promises: array<Promise<T>>) → Promise<array<T>>

Accepts an array of Promises and returns a new promise that:

  • is resolved after all input promises resolve.
  • is rejected if ANY input promises reject. Note: Only the first return value from each promise will be present in the resulting array.

After any input Promise rejects, all other input Promises that are still pending will be cancelled if they have no other consumers.

Parameters

Name Type Required
promises array<Promise<T>>

Returns

Type
Promise<array<T>>

# allSettled static

Promise.allSettled(promises: array<Promise<T>>) → Promise<array<PromiseStatus>>

Accepts an array of Promises and returns a new Promise that resolves with an array of in-place PromiseStatuses when all input Promises have settled. This is equivalent to mapping promise:finally over the array of Promises.

Parameters

Name Type Required
promises array<Promise<T>>

Returns

Type
Promise<array<PromiseStatus>>

# race static

Promise.race(promises: array<Promise<T>>) → Promise<T>

Accepts an array of Promises and returns a new promise that is resolved or rejected as soon as any Promise in the array resolves or rejects.

All other Promises that don't win the race will be cancelled if they have no other consumers.

Parameters

Name Type Required
promises array<Promise<T>>

Returns

Type
Promise<T>

# some static

Promise.some(

promises: array<Promise<T>>,
count: number
) → Promise<array<T>>

Accepts an array of Promises and returns a Promise that is resolved as soon as count Promises are resolved from the input array. The resolved array values are in the order that the Promises resolved in. When this Promise resolves, all other pending Promises are cancelled if they have no other consumers.

count 0 results in an empty array. The resultant array will never have more than count elements.

Parameters

Name Type Required
promises array<Promise<T>>
count number

Returns

Type
Promise<array<T>>

# any static

Promise.any(promises: array<Promise<T>>) → Promise<T>

Accepts an array of Promises and returns a Promise that is resolved as soon as any of the input Promises resolves. It will reject only if all input Promises reject. As soon as one Promises resolves, all other pending Promises are cancelled if they have no other consumers.

Resolves directly with the value of the first resolved Promise. This is essentially Promise.some with 1 count, except the Promise resolves with the value directly instead of an array with one element.

Parameters

Name Type Required
promises array<Promise<T>>

Returns

Type
Promise<T>

# delay static

Promise.delay(seconds: number) → Promise<number>

Returns a Promise that resolves after seconds seconds have passed. The Promise resolves with the actual amount of time that was waited.

This function is not a wrapper around wait. Promise.delay uses a custom scheduler which provides more accurate timing. As an optimization, cancelling this Promise instantly removes the task from the scheduler.

Passing NaN, infinity, or a number less than 1/60 is equivalent to passing 1/60.

Parameters

Name Type Required
seconds number

Returns

Type
Promise<number>

# is static

Promise.is(object: any) → boolean

Returns whether the given object is a Promise. This only checks if the object is a table and has an andThen method.

Parameters

Name Type Required
object any

Returns

Type
boolean

true if the given object is a Promise.

Instance Methods

# andThen

1. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

2. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

3. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

4. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

5. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

6. Promise.andThen(

successHandler: function(...?: ...any) → ...any,
failureHandler?: function(...?: ...any) → ...any
) → Promise<...any>

7. Promise.andThen(

successHandler: function(...?: ...any) → Promise<T>,
failureHandler?: function(...?: ...any) → Promise<T>
) → Promise<T>

Chains onto an existing Promise and returns a new Promise.

Return a Promise from the success or failure handler and it will be chained onto.

📚 Showing overload 1 of 7

Parameters

Name Type Required
successHandler

function(...?: ...any) → ...any

Details

Parameters

Name Type Required
... ...any

Returns

Type
...any?
failureHandler

function(...?: ...any) → ...any

Details

Parameters

Name Type Required
... ...any

Returns

Type
...any?

Returns

Type
Promise<...any?>

# catch

1. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

2. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

3. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

4. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

5. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

6. Promise.catch(failureHandler: function(...?: ...any) → ...any) → Promise<...any>

7. Promise.catch(failureHandler: function(...?: ...any) → Promise<T>) → Promise<T>

Shorthand for Promise:andThen(nil, failureHandler).

📚 Showing overload 1 of 7

Parameters

Name Type Required
failureHandler

function(...?: ...any) → ...any

Details

Parameters

Name Type Required
... ...any

Returns

Type
...any?

Returns

Type
Promise<...any?>

# tap

Promise.tap(tapHandler: function(...?: ...any) → ...any) → Promise<...any>

Similar to Promise.andThen, except the return value is the same as the value passed to the handler. In other words, you can insert a :tap into a Promise chain without affecting the value that downstream Promises receive.

  getTheValue()
    :tap(print)
    :andThen(function(theValue)
      print("Got", theValue, "even though print returns nil!")
    end)

If you return a Promise from the tap handler callback, its value will be discarded but tap will still wait until it resolves before passing the original value through.

Parameters

Name Type Required
tapHandler

function(...?: ...any) → ...any

Details

Parameters

Name Type Required
... ...any

Returns

Type
...any?

Returns

Type
Promise<...any?>

# finally

1. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

2. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

3. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

4. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

5. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

6. Promise.finally(finallyHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

7. Promise.finally(finallyHandler: function(status: PromiseStatus) → Promise<T>) → Promise<T>

Set a handler that will be called regardless of the promise's fate. The handler is called when the promise is resolved, rejected, or cancelled.

Returns a new promise chained from this promise.

📚 Showing overload 1 of 7

Parameters

Name Type Required
finallyHandler

function(status: PromiseStatus) → ...any

Details

Parameters

Name Type Required
status PromiseStatus

Returns

Type
...any?

Returns

Type
Promise<...any?>

# done

1. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

2. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

3. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

4. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

5. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

6. Promise.done(doneHandler: function(status: PromiseStatus) → ...any) → Promise<...any>

7. Promise.done(doneHandler: function(status: PromiseStatus) → Promise<T>) → Promise<T>

Set a handler that will be called only if the Promise resolves or is cancelled. This method is similar to finally, except it doesn't catch rejections.

done should be reserved specifically when you want to perform some operation after the Promise is finished (like finally), but you don't want to consume rejections (like in this example). You should use andThen instead if you only care about the Resolved case.

Like finally, if the Promise is cancelled, any Promises chained off of it with andThen won't run. Only Promises chained with done and finally will run in the case of cancellation.

Returns a new promise chained from this promise.

📚 Showing overload 1 of 7

Parameters

Name Type Required
doneHandler

function(status: PromiseStatus) → ...any

Details

Parameters

Name Type Required
status PromiseStatus

Returns

Type
...any?

Returns

Type
Promise<...any?>

# andThenCall

Promise.andThenCall(

callback: function(...?: ...any) → any,
...?: ...any
) → Promise

Attaches an andThen handler to this Promise that calls the given callback with the predefined arguments. The resolved value is discarded.

  promise:andThenCall(someFunction, "some", "arguments")

This is sugar for

  promise:andThen(function()
    return someFunction("some", "arguments")
  end)

Parameters

Name Type Required
callback

function(...?: ...any) → any

Details

Parameters

Name Type Required
... ...any

Returns

Type
any
... ...any

Arguments which will be passed to the callback.

Returns

Type
Promise

# finallyCall

Promise.finallyCall(

callback: function(...?: ...any) → any,
...?: ...any
) → Promise

Same as andThenCall, except for finally.

Attaches a finally handler to this Promise that calls the given callback with the predefined arguments.

Parameters

Name Type Required
callback

function(...?: ...any) → any

Details

Parameters

Name Type Required
... ...any

Returns

Type
any
... ...any

Arguments which will be passed to the callback.

Returns

Type
Promise

# doneCall

Promise.doneCall(

callback: function(...?: ...any) → any,
...?: ...any
) → Promise

Same as andThenCall, except for done.

Attaches a done handler to this Promise that calls the given callback with the predefined arguments.

Parameters

Name Type Required
callback

function(...?: ...any) → any

Details

Parameters

Name Type Required
... ...any

Returns

Type
any
... ...any

Arguments which will be passed to the callback.

Returns

Type
Promise

# andThenReturn

Promise.andThenReturn(...?: ...any) → Promise<...any>

Attaches an andThen handler to this Promise that discards the resolved value and returns the given value from it.

  promise:andThenReturn("some", "values")

This is sugar for

  promise:andThen(function()
    return "some", "values"
  end)

Promises are eager, so if you pass a Promise to andThenReturn, it will begin executing before andThenReturn is reached in the chain. Likewise, if you pass a Promise created from Promise.reject into andThenReturn, it's possible that this will trigger the unhandled rejection warning. If you need to return a Promise, it's usually best practice to use Promise.andThen.

Parameters

Name Type Required
... ...any

Values to return from the function.

Returns

Type
Promise<...any?>

# finallyReturn

Promise.finallyReturn(...?: ...any) → Promise<...any>

Attaches a finally handler to this Promise that discards the resolved value and returns the given value from it.

  promise:finallyReturn("some", "values")

This is sugar for

  promise:finally(function()
    return "some", "values"
  end)

Parameters

Name Type Required
... ...any

Values to return from the function.

Returns

Type
Promise<...any?>

# doneReturn

Promise.doneReturn(...?: ...any) → Promise<...any>

Attaches a done handler to this Promise that discards the resolved value and returns the given value from it.

  promise:doneReturn("some", "values")

This is sugar for

  promise:done(function()
    return "some", "values"
  end)

Parameters

Name Type Required
... ...any

Values to return from the function.

Returns

Type
Promise<...any?>

# timeout

Promise.timeout(

seconds: number,
rejectionValue?: any
) → Promise<T>

Returns a new Promise that resolves if the chained Promise resolves within seconds seconds, or rejects if execution time exceeds seconds. The chained Promise will be cancelled if the timeout is reached.

Sugar for:

Promise.race({
  Promise.delay(seconds):andThen(function()
    return Promise.reject(rejectionValue == nil and "Timed out" or rejectionValue)
  end),
  promise
})

Parameters

Name Type Required
seconds number
rejectionValue any

Returns

Type
Promise<T>

# cancel

Promise.cancel() →

Cancels this promise, preventing the promise from resolving or rejecting. Does not do anything if the promise is already settled.

Cancellations will propagate upwards and downwards through chained promises.

Promises will only be cancelled if all of their consumers are also cancelled. This is to say that if you call andThen twice on the same promise, and you cancel only one of the child promises, it will not cancel the parent promise until the other child promise is also cancelled.

Returns

Type

# await yields

Promise.await() → boolean, ...any

Yields the current thread until the given Promise completes. Returns true if the Promise resolved, followed by the values that the promise resolved or rejected with.

If the Promise gets cancelled, this function will return false, which is indistinguishable from a rejection. If you need to differentiate, you should use Promise.awaitStatus instead.

Returns

Type
boolean

true if the Promise successfully resolved.

...any?

The values that the Promise resolved or rejected with.

# awaitStatus yields

Promise.awaitStatus() → PromiseStatus, ...any

Yields the current thread until the given Promise completes. Returns the Promise's status, followed by the values that the promise resolved or rejected with.

Returns

Type
PromiseStatus

The Promise's status.

...any?

The values that the Promise resolved or rejected with.

# expect yields

Promise.expect() → ...any

Yields the current thread until the given Promise completes. Returns the the values that the promise resolved with.

This is essentially sugar for:

select(2, assert(promise:await()))

Errors if the Promise rejects or gets cancelled.

Returns

Type
...any?

The values that the Promise resolved with.

# getStatus

Promise.getStatus() → PromiseStatus

Returns the current Promise status.

Returns

Type
PromiseStatus