mirror of
https://github.com/AmberGraceRblx/luau-promise.git
synced 2025-04-24 15:50:01 +00:00
Add calls, awaitValue
This commit is contained in:
parent
3d53e7a364
commit
783eb1c2bb
4 changed files with 122 additions and 32 deletions
|
@ -1,3 +1,8 @@
|
|||
# 2.1.0
|
||||
|
||||
- Add `finallyCall`, `andThenCall`
|
||||
- Add `awaitValue`
|
||||
|
||||
# 2.0.0
|
||||
|
||||
- Add Promise.race
|
||||
|
|
|
@ -52,7 +52,7 @@ end
|
|||
## Cancellable animation sequence
|
||||
The following is an example of an animation sequence which is composable and cancellable. If the sequence is cancelled, the animated part will instantly jump to the end position as if it had played all the way through.
|
||||
|
||||
We use `finally` instead of `andThen` because we want the Promises to run even if the Promise is cancelled. We handle the case of the Promise being cancelled with the `onCancel` function.
|
||||
We use <ApiLink to="Promise.finallyCall" />, which uses `finally` internally, instead of `andThen` because we want the Promises to run even if the Promise is cancelled. We handle the case of the Promise being cancelled with the `onCancel` function.
|
||||
|
||||
We take advantage of Promise chaining by returning Promises from the `finally` handler functions. Because of this behavior, cancelling the final Promise in the chain will propagate up to the very top and cancel every single Promise you see here.
|
||||
|
||||
|
@ -69,42 +69,38 @@ local function apply(obj, props)
|
|||
end
|
||||
|
||||
local function runTween(obj, props)
|
||||
return function()
|
||||
return Promise.new(function(resolve, reject, onCancel)
|
||||
local tween = TweenService:Create(obj, TweenInfo.new(0.5), props)
|
||||
|
||||
if onCancel(function()
|
||||
tween:Cancel()
|
||||
apply(obj, props)
|
||||
end) then return end
|
||||
|
||||
tween.Completed:Connect(resolve)
|
||||
tween:Play()
|
||||
end)
|
||||
end
|
||||
return Promise.new(function(resolve, reject, onCancel)
|
||||
local tween = TweenService:Create(obj, TweenInfo.new(0.5), props)
|
||||
|
||||
if onCancel(function()
|
||||
tween:Cancel()
|
||||
apply(obj, props)
|
||||
end) then return end
|
||||
|
||||
tween.Completed:Connect(resolve)
|
||||
tween:Play()
|
||||
end)
|
||||
end
|
||||
|
||||
local function runAnimation(part, intensity)
|
||||
return function()
|
||||
return Promise.resolve()
|
||||
:finally(sleep(1))
|
||||
:finally(runTween(part, {
|
||||
Reflectance = 1 * intensity
|
||||
})):finally(runTween(part, {
|
||||
CFrame = CFrame.new(part.Position) *
|
||||
CFrame.Angles(0, math.rad(90 * intensity), 0)
|
||||
})):finally(runTween(part, {
|
||||
Size = (
|
||||
Vector3.new(10, 10, 10) * intensity
|
||||
) + Vector3.new(1, 1, 1)
|
||||
}))
|
||||
end
|
||||
return Promise.resolve()
|
||||
:finallyCall(sleep, 1))
|
||||
:finallyCall(runTween, part, {
|
||||
Reflectance = 1 * intensity
|
||||
}):finallyCall(runTween, part, {
|
||||
CFrame = CFrame.new(part.Position) *
|
||||
CFrame.Angles(0, math.rad(90 * intensity), 0)
|
||||
}):finallyCall(runTween, part, {
|
||||
Size = (
|
||||
Vector3.new(10, 10, 10) * intensity
|
||||
) + Vector3.new(1, 1, 1)
|
||||
})
|
||||
end
|
||||
|
||||
local animation = Promise.resolve() -- Begin Promise chain
|
||||
:finally(runAnimation(workspace.Part, 1))
|
||||
:finally(sleep(1))
|
||||
:finally(runAnimation(workspace.Part, 0))
|
||||
:finallyCall(runAnimation, workspace.Part, 1)
|
||||
:finallyCall(sleep, 1)
|
||||
:finallyCall(runAnimation, workspace.Part, 0)
|
||||
|
||||
wait(2)
|
||||
animation:cancel() -- Remove this line to see the full animation
|
||||
|
|
|
@ -261,7 +261,47 @@ docs:
|
|||
returns: Promise<T>
|
||||
returns: Promise<T>
|
||||
|
||||
- name: andThenCall
|
||||
desc: |
|
||||
Attaches an `andThen` handler to this Promise that calls the given callback with the predefined arguments. The resolved value is discarded.
|
||||
|
||||
```lua
|
||||
promise:andThenCall(someFunction, "some", "arguments")
|
||||
```
|
||||
|
||||
This is sugar for
|
||||
|
||||
```lua
|
||||
promise:andThen(function()
|
||||
return callback(...args)
|
||||
end)
|
||||
```
|
||||
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: finallyCall
|
||||
desc: |
|
||||
Same as `andThenCall`, except for `finally`.
|
||||
|
||||
Attaches a `finally` 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: cancel
|
||||
desc: |
|
||||
|
@ -272,7 +312,12 @@ docs:
|
|||
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.
|
||||
|
||||
- name: await
|
||||
desc: 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.
|
||||
desc: |
|
||||
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.
|
||||
|
||||
::: warning
|
||||
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:
|
||||
- desc: "`true` if the Promise successfully resolved."
|
||||
type: boolean
|
||||
|
@ -286,6 +331,14 @@ docs:
|
|||
desc: The Promise's status.
|
||||
- type: ...any?
|
||||
desc: The values that the Promise resolved or rejected with.
|
||||
- name: awaitValue
|
||||
desc: |
|
||||
Yields the current thread until the given Promise completes. Returns the the values that the promise resolved with.
|
||||
|
||||
Errors if the Promise rejects or gets cancelled.
|
||||
returns:
|
||||
- type: ...any?
|
||||
desc: The values that the Promise resolved with.
|
||||
|
||||
- name: getStatus
|
||||
desc: Returns the current Promise status.
|
||||
|
|
36
lib/init.lua
36
lib/init.lua
|
@ -400,6 +400,16 @@ function Promise.prototype:catch(failureCallback)
|
|||
return self:andThen(nil, failureCallback)
|
||||
end
|
||||
|
||||
--[[
|
||||
Calls a callback on `andThen` with specific arguments.
|
||||
]]
|
||||
function Promise.prototype:andThenCall(callback, ...)
|
||||
local length, values = pack(...)
|
||||
return self:andThen(function()
|
||||
return callback(unpack(values, 1, length))
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Cancels the promise, disallowing it from rejecting or resolving, and calls
|
||||
the cancellation hook if provided.
|
||||
|
@ -466,6 +476,16 @@ function Promise.prototype:finally(finallyHandler)
|
|||
end, self)
|
||||
end
|
||||
|
||||
--[[
|
||||
Calls a callback on `finally` with specific arguments.
|
||||
]]
|
||||
function Promise.prototype:finallyCall(callback, ...)
|
||||
local length, values = pack(...)
|
||||
return self:finally(function()
|
||||
return callback(unpack(values, 1, length))
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
Yield until the promise is completed.
|
||||
|
||||
|
@ -504,6 +524,22 @@ function Promise.prototype:await(...)
|
|||
return status == Promise.Status.Resolved, unpack(result, 1, length - 1)
|
||||
end
|
||||
|
||||
--[[
|
||||
Calls await and only returns if the Promise resolves.
|
||||
Throws if the Promise rejects or gets cancelled.
|
||||
]]
|
||||
function Promise.prototype:awaitValue(...)
|
||||
local length, result = pack(self:awaitStatus(...))
|
||||
local status = table.remove(result, 1)
|
||||
|
||||
assert(
|
||||
status == Promise.Status.Resolved,
|
||||
tostring(result[1] == nil and "" or result[1])
|
||||
)
|
||||
|
||||
return unpack(result, 1, length - 1)
|
||||
end
|
||||
|
||||
--[[
|
||||
Intended for use in tests.
|
||||
|
||||
|
|
Loading…
Reference in a new issue