Promises and Why You Should Use Them

How would I build a recursive Promise that runs itself when it rejects until it successfully resolves?

1 Like

Promises are eager which means that the instant you create a Promise it’s already running. Thus there’s no way to re-run a Promise per se. To retry the same operation, you’d need to have a new Promise for each attempt. That usually boils down to calling the function multiple times.

Something like this:

local function retry(callback, times, ...)
  local args, length = {...}, select("#", ...)

  return callback(...):catch(function(...)
    if times > 0 then
      return retry(callback, times - 1, unpack(args, 1, length)) 
    else
      return Promise.reject(...)
    end
  end)
end

local function test(value)
	return Promise.new(function(resolve, reject)
		(math.random() >= 0.95 and resolve or reject)(value)
	end)
end


print(retry(test, 10, "hello world"):awaitStatus())
8 Likes

Although, is there’s any cases where Promises were used for any game mechanics just so i can get a clear vision.

1 Like

Hi,

I’m not too experienced with threading so bear with me on this one; in your documentation and various devforum posts you outline how spawn and wait functions aren’t ideal which was helpful. However, in the usage guide wait() is used within a Promise, so, in general, how should wait be used if at all?

1 Like

I don’t think it should be used at all. wait was used there because it’s a simple function that yields and everyone understands.

I’m working on v2 of the Promise library right now and with that I want to write a more comprehensive usage guide that makes things a lot more clear. I’ll make sure to avoid the wait function in that new version to avoid confusion

Promise.delay is how I recommend waiting for some amount of time.

5 Likes

Haven’t fully read the post, so maybe you explain it later on, but when I wrote the first promise example you have given.
(Which is:

local HttpService = game:GetService("HttpService")
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

)

I got a warning “Unknown global ‘Promise’”
Can you help me? :slight_smile:

You haven’t defined what “Promise” is.
In OPs code, promise is set to local promise = httpGet("https://google.com")

Please read the full thread before replying next time.

You didn’t require the Promise library, which was omitted from the example code.
If you’ve already placed the Promise library into the game, just put local Promise = require(path.to.Promise) at the top of your code.

2 Likes

What’s the resolve and reject parameter in Promise.new() suppose to be? Am I suppose to pass some kind of resolve and reject argument inside of them? I didn’t see the httpget example pass anything into the Promise.async()

OMG its JavaScript/like promises

1 Like

@evaera, Just want to verify that it is the init.lua file in your repo that is the Promise.lua file we should be using?

1 Like

hey! thanks for this wonderful open source module you posted but for some reason when I try to run this, it says its an unhandled promise rejection. Whats wrong with this code?

– Code

local tabNaruto = {Naruto = 5}

local function promiseCal(callback)

Promise.try(function()

return callback() and “ok” or error(“Oh an error!”)

end)

end

promiseCal(function()

print(tabNaruto.Naruto.shirt)

end):andThen(function(message)

print(message)

end):catch(function(err)

print(string.format(“Error: %s”, err))

end)

1 Like

The Roblox community has benefited greatly from promises and coroutines. They provide us the tools we need to construct a far more dependable manner of creating code and accessing data. Furthermore, it is open source, which means that anybody may contribute to the community and help keep it up to date.

1 Like

hey. i’m using your module in my roblox game and I have a small problem. When I cancel a running promise, it sends an error “cannot resume dead coroutine”, Idk how to fix this, it doesnt give me any problem but it bother me to check the output or something like this.
Example

local promise = require(...)
local _promise = promise.new(function(resolve, reject, onCancel)
    wait(5)
    print("Resolved")
    resolve()
end)

wait(2)
_promise:cancel() --> cancel the coroutine but after the _promise wait finishes, it gives me an error "cannot resume dead coroutine"

If you could help me with that problem thx!

You added a wait(2) before canceling and by that time your promise is already settled, meaning no point in canceling.
Documentation: Promise | roblox-lua-promise

Yeah Ik I did it to see the difference
The problem isn’t that, the problem is when I’m cancelling a promise which have a wait or which is yielding, I get an error “cannot resume dead coroutine”, it is the same for coroutines

This is because you’re using legacy wait, which doesn’t check whether the thread is dead or not before trying to resume the thread. This causes the error, as promises kill the thread before wait is done yielding. In this case, you can just change wait to task.wait and it should work without outputting the error.

This happens with other things too unfortunately, like with RemoteFunctions, BindableFunctions for example, since they don’t either check whether the thread is dead or not before trying to resume the thread.

Here’s a bug report for it.

1 Like

Hello, sorry for bumping into this old topic. Does this module support Typechecking? From the looks of it; there doesn’t seem to be any. Thanks!

Type checking a promise is not possible at the moment, recursive types are not supported at the moment

Promise was mostly superseeded by red-blox’s future library!