Implement Promise.retryWithDelay

Closes #45
This commit is contained in:
eryn L. K 2021-12-27 22:23:18 -05:00
parent eb3f2e77e2
commit 3138dab77a
2 changed files with 61 additions and 0 deletions

View file

@ -1925,6 +1925,36 @@ function Promise.retry(callback, times, ...)
end)
end
--[=[
Repeatedly calls a Promise-returning function up to `times` number of times, waiting `seconds` seconds between each
retry, until the returned Promise resolves.
If the amount of retries is exceeded, the function will return the latest rejected Promise.
@since v3.2.0
@param callback (...: P) -> Promise<T>
@param times number
@param seconds number
@param ...? P
]=]
function Promise.retryWithDelay(callback, times, seconds, ...)
assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function")
assert(type(times) == "number", "Parameter #2 (times) to Promise.retry must be a number")
assert(type(seconds) == "number", "Parameter #3 (seconds) to Promise.retry must be a number")
local args, length = { ... }, select("#", ...)
return Promise.resolve(callback(...)):catch(function(...)
if times > 0 then
Promise.delay(seconds):await()
return Promise.retryWithDelay(callback, times - 1, seconds, unpack(args, 1, length))
else
return Promise.reject(...)
end
end)
end
--[=[
Converts an event into a Promise which resolves the next time the event fires.

View file

@ -1611,6 +1611,37 @@ return function()
end)
end)
describe("Promise.retryWithDelay", function()
it("should retry after a delay", function()
local counter = 0
local promise = Promise.retryWithDelay(function(parameter)
expect(parameter).to.equal("foo")
counter = counter + 1
if counter == 3 then
return Promise.resolve("ok")
end
return Promise.reject("fail")
end, 3, 10, "foo")
expect(counter).to.equal(1)
advanceTime(11)
expect(counter).to.equal(2)
advanceTime(11)
expect(counter).to.equal(3)
expect(promise:getStatus()).to.equal(Promise.Status.Resolved)
expect(promise._values[1]).to.equal("ok")
end)
end)
describe("Promise.fromEvent", function()
it("should convert a Promise into an event", function()
local event = Instance.new("BindableEvent")