mirror of
https://github.com/AmberGraceRblx/luau-promise.git
synced 2025-04-24 23:50:03 +00:00
parent
3052ec1474
commit
bb13a0e2b6
4 changed files with 267 additions and 2 deletions
|
@ -8,6 +8,8 @@
|
||||||
- Improve stack traces
|
- Improve stack traces
|
||||||
- Promise.promisify will now turn errors into rejections even if they occur after a yield.
|
- Promise.promisify will now turn errors into rejections even if they occur after a yield.
|
||||||
- Add Promise.try
|
- Add Promise.try
|
||||||
|
- Add `done`, `doneCall`, `doneReturn`
|
||||||
|
- Add `andThenReturn`, `finallyReturn`
|
||||||
|
|
||||||
# 2.4.0
|
# 2.4.0
|
||||||
|
|
||||||
|
|
106
lib/README.md
106
lib/README.md
|
@ -322,6 +322,31 @@ docs:
|
||||||
returns: Promise<T>
|
returns: Promise<T>
|
||||||
returns: Promise<T>
|
returns: Promise<T>
|
||||||
|
|
||||||
|
- name: done
|
||||||
|
desc: |
|
||||||
|
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.
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
If this 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.
|
||||||
|
params:
|
||||||
|
- name: doneHandler
|
||||||
|
type:
|
||||||
|
kind: function
|
||||||
|
params: "status: PromiseStatus"
|
||||||
|
returns: ...any?
|
||||||
|
returns: Promise<...any?>
|
||||||
|
overloads:
|
||||||
|
- params:
|
||||||
|
- name: doneHandler
|
||||||
|
type:
|
||||||
|
kind: function
|
||||||
|
params: "status: PromiseStatus"
|
||||||
|
returns: Promise<T>
|
||||||
|
returns: Promise<T>
|
||||||
|
|
||||||
- name: andThenCall
|
- name: andThenCall
|
||||||
desc: |
|
desc: |
|
||||||
Attaches an `andThen` handler to this Promise that calls the given callback with the predefined arguments. The resolved value is discarded.
|
Attaches an `andThen` handler to this Promise that calls the given callback with the predefined arguments. The resolved value is discarded.
|
||||||
|
@ -364,6 +389,87 @@ docs:
|
||||||
desc: Arguments which will be passed to the callback.
|
desc: Arguments which will be passed to the callback.
|
||||||
returns: Promise
|
returns: Promise
|
||||||
|
|
||||||
|
- name: doneCall
|
||||||
|
desc: |
|
||||||
|
Same as `andThenCall`, except for `done`.
|
||||||
|
|
||||||
|
Attaches a `done` handler to this Promise that calls the given callback with the predefined arguments.
|
||||||
|
params:
|
||||||
|
- name: callback
|
||||||
|
type:
|
||||||
|
kind: function
|
||||||
|
params: "...: ...any?"
|
||||||
|
returns: "any"
|
||||||
|
- name: "..."
|
||||||
|
type: "...any?"
|
||||||
|
desc: Arguments which will be passed to the callback.
|
||||||
|
returns: Promise
|
||||||
|
|
||||||
|
- name: andThenReturn
|
||||||
|
desc: |
|
||||||
|
Attaches an `andThen` handler to this Promise that discards the resolved value and returns the given value from it.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:andThenReturn("some", "values")
|
||||||
|
```
|
||||||
|
|
||||||
|
This is sugar for
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:andThen(function()
|
||||||
|
return "some", "values"
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
params:
|
||||||
|
- name: "..."
|
||||||
|
type: "...any?"
|
||||||
|
desc: Values to return from the function.
|
||||||
|
returns: Promise<...any?>
|
||||||
|
|
||||||
|
- name: finallyReturn
|
||||||
|
desc: |
|
||||||
|
Attaches a `finally` handler to this Promise that discards the resolved value and returns the given value from it.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:finallyReturn("some", "values")
|
||||||
|
```
|
||||||
|
|
||||||
|
This is sugar for
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:finally(function()
|
||||||
|
return "some", "values"
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
params:
|
||||||
|
- name: "..."
|
||||||
|
type: "...any?"
|
||||||
|
desc: Values to return from the function.
|
||||||
|
returns: Promise<...any?>
|
||||||
|
|
||||||
|
- name: doneReturn
|
||||||
|
desc: |
|
||||||
|
Attaches a `done` handler to this Promise that discards the resolved value and returns the given value from it.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:doneReturn("some", "values")
|
||||||
|
```
|
||||||
|
|
||||||
|
This is sugar for
|
||||||
|
|
||||||
|
```lua
|
||||||
|
promise:done(function()
|
||||||
|
return "some", "values"
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
|
params:
|
||||||
|
- name: "..."
|
||||||
|
type: "...any?"
|
||||||
|
desc: Values to return from the function.
|
||||||
|
returns: Promise<...any?>
|
||||||
|
|
||||||
|
|
||||||
- name: cancel
|
- name: cancel
|
||||||
desc: |
|
desc: |
|
||||||
Cancels this promise, preventing the promise from resolving or rejecting. Does not do anything if the promise is already settled.
|
Cancels this promise, preventing the promise from resolving or rejecting. Does not do anything if the promise is already settled.
|
||||||
|
|
69
lib/init.lua
69
lib/init.lua
|
@ -502,6 +502,16 @@ function Promise.prototype:andThenCall(callback, ...)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Shorthand for an andThen handler that returns the given value.
|
||||||
|
]]
|
||||||
|
function Promise.prototype:andThenReturn(...)
|
||||||
|
local length, values = pack(...)
|
||||||
|
return self:_andThen(debug.traceback(), function()
|
||||||
|
return unpack(values, 1, length)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Cancels the promise, disallowing it from rejecting or resolving, and calls
|
Cancels the promise, disallowing it from rejecting or resolving, and calls
|
||||||
the cancellation hook if provided.
|
the cancellation hook if provided.
|
||||||
|
@ -548,8 +558,10 @@ end
|
||||||
Used to set a handler for when the promise resolves, rejects, or is
|
Used to set a handler for when the promise resolves, rejects, or is
|
||||||
cancelled. Returns a new promise chained from this promise.
|
cancelled. Returns a new promise chained from this promise.
|
||||||
]]
|
]]
|
||||||
function Promise.prototype:_finally(traceback, finallyHandler)
|
function Promise.prototype:_finally(traceback, finallyHandler, onlyOk)
|
||||||
self._unhandledRejection = false
|
if not onlyOk then
|
||||||
|
self._unhandledRejection = false
|
||||||
|
end
|
||||||
|
|
||||||
-- Return a promise chained off of this promise
|
-- Return a promise chained off of this promise
|
||||||
return Promise._new(traceback, function(resolve, reject)
|
return Promise._new(traceback, function(resolve, reject)
|
||||||
|
@ -563,6 +575,17 @@ function Promise.prototype:_finally(traceback, finallyHandler)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if onlyOk then
|
||||||
|
local callback = finallyCallback
|
||||||
|
finallyCallback = function(...)
|
||||||
|
if self._status == Promise.Status.Rejected then
|
||||||
|
return resolve(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
return callback(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self._status == Promise.Status.Started then
|
if self._status == Promise.Status.Started then
|
||||||
-- The promise is not settled, so queue this.
|
-- The promise is not settled, so queue this.
|
||||||
table.insert(self._queuedFinally, finallyCallback)
|
table.insert(self._queuedFinally, finallyCallback)
|
||||||
|
@ -592,6 +615,48 @@ function Promise.prototype:finallyCall(callback, ...)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Shorthand for a finally handler that returns the given value.
|
||||||
|
]]
|
||||||
|
function Promise.prototype:finallyReturn(...)
|
||||||
|
local length, values = pack(...)
|
||||||
|
return self:_finally(debug.traceback(), function()
|
||||||
|
return unpack(values, 1, length)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Similar to finally, except rejections are propagated through it.
|
||||||
|
]]
|
||||||
|
function Promise.prototype:done(finallyHandler)
|
||||||
|
assert(
|
||||||
|
finallyHandler == nil or type(finallyHandler) == "function",
|
||||||
|
ERROR_NON_FUNCTION:format("Promise:finallyO")
|
||||||
|
)
|
||||||
|
return self:_finally(debug.traceback(), finallyHandler, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Calls a callback on `done` with specific arguments.
|
||||||
|
]]
|
||||||
|
function Promise.prototype:doneCall(callback, ...)
|
||||||
|
assert(type(callback) == "function", ERROR_NON_FUNCTION:format("Promise:doneCall"))
|
||||||
|
local length, values = pack(...)
|
||||||
|
return self:_finally(debug.traceback(), function()
|
||||||
|
return callback(unpack(values, 1, length))
|
||||||
|
end, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Shorthand for a done handler that returns the given value.
|
||||||
|
]]
|
||||||
|
function Promise.prototype:doneReturn(...)
|
||||||
|
local length, values = pack(...)
|
||||||
|
return self:_finally(debug.traceback(), function()
|
||||||
|
return unpack(values, 1, length)
|
||||||
|
end, true)
|
||||||
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Yield until the promise is completed.
|
Yield until the promise is completed.
|
||||||
|
|
||||||
|
|
|
@ -416,6 +416,18 @@ return function()
|
||||||
expect(p2._parent).to.equal(p1)
|
expect(p2._parent).to.equal(p1)
|
||||||
expect(p1._consumers[p2]).to.equal(true)
|
expect(p1._consumers[p2]).to.equal(true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("should forward return values", function()
|
||||||
|
local value
|
||||||
|
|
||||||
|
Promise.resolve():finally(function()
|
||||||
|
return 1
|
||||||
|
end):andThen(function(v)
|
||||||
|
value = v
|
||||||
|
end)
|
||||||
|
|
||||||
|
expect(value).to.equal(1)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("Promise.all", function()
|
describe("Promise.all", function()
|
||||||
|
@ -698,4 +710,84 @@ return function()
|
||||||
expect(errorText:find("errortext")).to.be.ok()
|
expect(errorText:find("errortext")).to.be.ok()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe("Promise:andThenReturn", function()
|
||||||
|
it("should return the given values", function()
|
||||||
|
local value1, value2
|
||||||
|
|
||||||
|
Promise.resolve():andThenReturn(1, 2):andThen(function(one, two)
|
||||||
|
value1 = one
|
||||||
|
value2 = two
|
||||||
|
end)
|
||||||
|
|
||||||
|
expect(value1).to.equal(1)
|
||||||
|
expect(value2).to.equal(2)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("Promise:doneReturn", function()
|
||||||
|
it("should return the given values", function()
|
||||||
|
local value1, value2
|
||||||
|
|
||||||
|
Promise.resolve():doneReturn(1, 2):andThen(function(one, two)
|
||||||
|
value1 = one
|
||||||
|
value2 = two
|
||||||
|
end)
|
||||||
|
|
||||||
|
expect(value1).to.equal(1)
|
||||||
|
expect(value2).to.equal(2)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("Promise:andThenCall", function()
|
||||||
|
it("should call the given function with arguments", function()
|
||||||
|
local value1, value2
|
||||||
|
Promise.resolve():andThenCall(function(a, b)
|
||||||
|
value1 = a
|
||||||
|
value2 = b
|
||||||
|
end, 3, 4)
|
||||||
|
|
||||||
|
expect(value1).to.equal(3)
|
||||||
|
expect(value2).to.equal(4)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("Promise:doneCall", function()
|
||||||
|
it("should call the given function with arguments", function()
|
||||||
|
local value1, value2
|
||||||
|
Promise.resolve():doneCall(function(a, b)
|
||||||
|
value1 = a
|
||||||
|
value2 = b
|
||||||
|
end, 3, 4)
|
||||||
|
|
||||||
|
expect(value1).to.equal(3)
|
||||||
|
expect(value2).to.equal(4)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("Promise:done", function()
|
||||||
|
it("should trigger on resolve or cancel", function()
|
||||||
|
local promise = Promise.new(function() end)
|
||||||
|
local value
|
||||||
|
|
||||||
|
local p = promise:done(function()
|
||||||
|
value = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
expect(value).to.never.be.ok()
|
||||||
|
promise:cancel()
|
||||||
|
expect(p:getStatus()).to.equal(Promise.Status.Cancelled)
|
||||||
|
expect(value).to.equal(true)
|
||||||
|
|
||||||
|
local never, always
|
||||||
|
Promise.reject():done(function()
|
||||||
|
never = true
|
||||||
|
end):finally(function()
|
||||||
|
always = true
|
||||||
|
end)
|
||||||
|
|
||||||
|
expect(never).to.never.be.ok()
|
||||||
|
expect(always).to.be.ok()
|
||||||
|
end)
|
||||||
|
end)
|
||||||
end
|
end
|
Loading…
Reference in a new issue