GDScript Promise Async Utils screenshot 1
K

Publisher

kurukmm

GDScript Promise Async Utils

Tools
Async Promise GDScript Coroutine Await Patterns Yield Task

Provide async functionality to have Promises similar to JavaScript with functions like Promise.all, Promise.race, Promise.any

GDScript Async Utils

This addons provides helpers for using the Promise class in GDScript to handle asynchronous operations.

Every function that must be await has a async prefix.

Developed and tested with Godot 4.1.3

Setup

Just copying Promise.gd

Godot Asset Library

  • Soon...

Basic Promise Usage

These examples demonstrate different ways to create, resolve, and work with promises.

Creating and Resolving a Promise

var promise = Promise.new()
promise.resolve()
await promise.async_awaiter()

Resolving a Promise with Data

var promise = Promise.new()
promise.resolve_with_data(5)
var data = await promise.async_awaiter()
# data will be 5

Resolving a Promise After a Delay

func wait_and_resolve_with_data(promise: Promise, data: Variant)
    await test.get_tree().create_timer(0.1).timeout
    promise.resolve_with_data(data)

var promise = Promise.new()
wait_and_resolve_with_data(promise, data)
var data = await promise.async_awaiter() # data will be 32 after some time

Rejecting a Promise

var promise = Promise.new()
promise.reject("Rejected")
var result = await promise.async_awaiter()
if result is Promise.Error:
    prints("Promise rejected, error:", result.get_error())

Using .then and .catch

var promise = Promise.new()
promise.resolve()
promise \
    .then(func (result):
        prints("Promise resolved", result)) \
    .catch(func (result):
        prints("Promise rejected", result))

| Note: If the promise was resolved/rejected, the callback is called inmediatly.

Advanced Promise Usage

Chaining promises

var promise1 = Promise.new()
var promise2 = Promise.new()
promise1.resolve_with_data(promise2)
promise2.resolve_with_data("Chained data")
var data = await promise1.async_awaiter()
print(data) # data will be "Chained data"

Handling multiple promises (Promise.async_all, Promise.async_any, Promise.async_Race)

Waiting for All Promises (Promise.async_all)

func wait_and_resolve_with_data(promise: Promise, data: Variant)
    await test.get_tree().create_timer(0.1).timeout
    promise.resolve_with_data(data)

var promise1 = Promise.new()
var promise2 = Promise.new()
wait_and_resolve_with_data(promise1, "Data 1")
wait_and_resolve_with_data(promise2, "Data 2")
var results = await Promise.async_all([promise1, promise2])
# results will be an array ["Data 1", "Data 2"]

Waiting for Any Promise to Resolve (Promise.async_any) (ignores rejections)

func wait_and_resolve_with_data(promise: Promise, data: Variant, time_secs: float)
    await test.get_tree().create_timer(time_secs).timeout
    promise.resolve_with_data(data)

var promise1 = Promise.new()
var promise2 = Promise.new()
wait_and_resolve_with_data(promise1, "Data 1", 0.3) # takes more time...
wait_and_resolve_with_data(promise2, "Data 2", 0.1)
var result = await Promise.async_any([promise1, promise2])
# result will be "Data 2" since promise1 takes more time

Racing Promises (Promise.async_race) (doesn't ignore rejections)

func wait_and_resolve_with_data(promise: Promise, data: Variant)
    await test.get_tree().create_timer(0.1).timeout
    promise.resolve_with_data(data)

var promise1 = Promise.new()
var promise2 = Promise.new()
wait_and_resolve_with_data(self, promise1, "Data 1")
promise2.reject("Rejected")
var result = await Promise.async_race([promise1, promise2])
# result will be either Promise.Error, because was resolved first

More examples

You can extract more examples in the tests

Async custom linter

For having mandatory async or _async in the prefix of a await you can use this custom linter:

Godot GDScript Toolkit with Async (fork)

Install

pip3 install git+https://github.com/kuruk-mm/godot-gdscript-toolkit.git

Usage

Linter (with async prefix requirement):

gdlint path

Format:

gdformat path

| Note: This is a fork from Scony repo https://github.com/Scony/godot-gdscript-toolkit