mirror of
https://github.com/AmberGraceRblx/luau-promise.git
synced 2025-04-24 15:50:01 +00:00
Update docs for v4
This commit is contained in:
parent
893c43a90c
commit
06fc407f12
4 changed files with 70 additions and 16 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,5 +1,22 @@
|
|||
# Changelog
|
||||
|
||||
## [4.0.0-rc.1] - 2021-12-28
|
||||
### Changed
|
||||
- `Promise:finally` no longer observes a rejection from a Promise. Calling `Promise:finally` is mostly transparent now.
|
||||
- The Promise returned by `Promise:finally` resolves or rejects with whatever the parent Promise resolved or rejected with. It will be cancelled if the parent Promise is cancelled.
|
||||
- The value returned from the `finally` handler is discarded now.
|
||||
- If the value returned from the `finally` handler is a Promise, we wait for it to resolve, but we do not use its value.
|
||||
- If the value returned from the `finally` handler is a Promise and it rejects, `finally` returns the new rejected value.
|
||||
- `Promise:finally` no longer counts as a consumer of the parent Promise for cancellation purposes. If all consumers are cancelled and the only remaining callbacks are finally handlers, the Promise is now cancelled.
|
||||
- The Promise executor thread is now closed with `coroutine.close` when the Promise is cancelled.
|
||||
- The Promise executor thread is now closed after the Promise settles (calling `resolve` or `reject`).
|
||||
- Callbacks enqueued with `andThen` and `catch` are now dequeued if the Promise returned by `andThen`/`catch` is cancelled.
|
||||
- Calling `andThen` or `catch` on an already-cancelled Promise now returns a cancelled Promise instead of returning a rejected Promise
|
||||
- `:await`, `:expect`, and `:awaitStatus` are no longer backed by BindableEvents, and now use the task library directly, so performance should be better.
|
||||
|
||||
### Removed
|
||||
- `Promise:done` and its associated members have been removed.
|
||||
|
||||
## [3.2.0] - 2021-12-27
|
||||
### Added
|
||||
- Add `Promise.onUnhandledRejection` global event
|
||||
|
|
|
@ -52,9 +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 [Promise.doneCall](/api/Promise#doneCall), which uses `done` 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 `done` 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.
|
||||
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.
|
||||
|
||||
```lua
|
||||
local Promise = require(game.ReplicatedStorage.Promise)
|
||||
|
@ -84,13 +82,13 @@ end
|
|||
|
||||
local function runAnimation(part, intensity)
|
||||
return Promise.resolve()
|
||||
:doneCall(sleep, 1)
|
||||
:doneCall(runTween, part, {
|
||||
:finallyCall(sleep, 1)
|
||||
:finallyCall(runTween, part, {
|
||||
Reflectance = 1 * intensity
|
||||
}):doneCall(runTween, part, {
|
||||
}):finallyCall(runTween, part, {
|
||||
CFrame = CFrame.new(part.Position) *
|
||||
CFrame.Angles(0, math.rad(90 * intensity), 0)
|
||||
}):doneCall(runTween, part, {
|
||||
}):finallyCall(runTween, part, {
|
||||
Size = (
|
||||
Vector3.new(10, 10, 10) * intensity
|
||||
) + Vector3.new(1, 1, 1)
|
||||
|
@ -98,9 +96,9 @@ local function runAnimation(part, intensity)
|
|||
end
|
||||
|
||||
local animation = Promise.resolve() -- Begin Promise chain
|
||||
:doneCall(runAnimation, workspace.Part, 1)
|
||||
:doneCall(sleep, 1)
|
||||
:doneCall(runAnimation, workspace.Part, 0)
|
||||
:finallyCall(runAnimation, workspace.Part, 1)
|
||||
:finallyCall(sleep, 1)
|
||||
:finallyCall(runAnimation, workspace.Part, 0)
|
||||
:catch(warn)
|
||||
|
||||
wait(2)
|
||||
|
|
|
@ -160,7 +160,7 @@ It's good practice to add an `onCancel` hook to all of your asynchronous Promise
|
|||
Even if you don't plan to directly cancel a particular Promise, chaining with other Promises can cause it to become automatically cancelled if no one cares about the value anymore.
|
||||
:::
|
||||
|
||||
If you attach a `:andThen` or `:catch` handler to a Promise after it's been cancelled, the chained Promise will be instantly rejected with `Promise.Error(Promise.Error.Kind.AlreadyCancelled)`. This also applies to Promises that you pass to `resolve`. However, `finally` does not have this constraint.
|
||||
If you attach a `:andThen` or `:catch` handler to a Promise after it's been cancelled, the chained Promise will be cancelled as well. This also applies to Promises that you pass to `resolve`.
|
||||
|
||||
:::warning
|
||||
If you cancel a Promise immediately after creating it without yielding in between, the fate of the Promise is dependent on if the Promise handler yields or not. If the Promise handler resolves without yielding, then the Promise will already be settled by the time you are able to cancel it, thus any consumers of the Promise will have already been called and cancellation is not possible.
|
||||
|
|
49
lib/init.lua
49
lib/init.lua
|
@ -337,6 +337,12 @@ end
|
|||
* You can set the cancellation hook at any time before resolving.
|
||||
* When a promise is cancelled, calls to `resolve` or `reject` will be ignored, regardless of if you set a cancellation hook or not.
|
||||
|
||||
:::caution
|
||||
If the Promise is cancelled, the `executor` thread is closed with `coroutine.close` after the cancellation hook is called.
|
||||
|
||||
You must perform any cleanup code in the cancellation hook: any time your executor yields, it **may never resume**.
|
||||
:::
|
||||
|
||||
@param executor (resolve: (...: any) -> (), reject: (...: any) -> (), onCancel: (abortHandler?: () -> ()) -> boolean) -> ()
|
||||
@return Promise
|
||||
]=]
|
||||
|
@ -1258,7 +1264,15 @@ end
|
|||
Within the failure handler, you should never assume that the rejection value is a string. Some rejections within the Promise library are represented by [[Error]] objects. If you want to treat it as a string for debugging, you should call `tostring` on it first.
|
||||
:::
|
||||
|
||||
Return a Promise from the success or failure handler and it will be chained onto.
|
||||
You can return a Promise from the success or failure handler and it will be chained onto.
|
||||
|
||||
Calling `andThen` on a cancelled Promise returns a cancelled Promise.
|
||||
|
||||
:::tip
|
||||
If the Promise returned by `andThen` is cancelled, `successHandler` and `failureHandler` will not run.
|
||||
|
||||
To run code no matter what, use [Promise:finally].
|
||||
:::
|
||||
|
||||
@param successHandler (...: any) -> ...any
|
||||
@param failureHandler? (...: any) -> ...any
|
||||
|
@ -1280,6 +1294,13 @@ end
|
|||
Within the failure handler, you should never assume that the rejection value is a string. Some rejections within the Promise library are represented by [[Error]] objects. If you want to treat it as a string for debugging, you should call `tostring` on it first.
|
||||
:::
|
||||
|
||||
Calling `catch` on a cancelled Promise returns a cancelled Promise.
|
||||
|
||||
:::tip
|
||||
If the Promise returned by `catch` is cancelled, `failureHandler` will not run.
|
||||
|
||||
To run code no matter what, use [Promise:finally].
|
||||
:::
|
||||
|
||||
@param failureHandler (...: any) -> ...any
|
||||
@return Promise<...any>
|
||||
|
@ -1485,12 +1506,30 @@ function Promise.prototype:_finally(traceback, finallyHandler)
|
|||
end
|
||||
|
||||
--[=[
|
||||
Set a handler that will be called regardless of the promise's fate. The handler is called when the promise is resolved, rejected, *or* cancelled.
|
||||
Set a handler that will be called regardless of the promise's fate. The handler is called when the promise is
|
||||
resolved, rejected, *or* cancelled.
|
||||
|
||||
Returns a new promise chained from this promise.
|
||||
Returns a new Promise that:
|
||||
- resolves with the same values that this Promise resolves with.
|
||||
- rejects with the same values that this Promise rejects with.
|
||||
- is cancelled if this Promise is cancelled.
|
||||
|
||||
:::caution
|
||||
If the Promise is cancelled, any Promises chained off of it with `andThen` won't run. Only Promises chained with `finally` or `done` will run in the case of cancellation.
|
||||
If the value you return from the handler is a Promise:
|
||||
- We wait for the Promise to resolve, but we ultimately discard the resolved value.
|
||||
- If the returned Promise rejects, the Promise returned from `finally` will reject with the rejected value from the
|
||||
*returned* promise.
|
||||
- If the `finally` Promise is cancelled, and you returned a Promise from the handler, we cancel that Promise too.
|
||||
|
||||
Otherwise, the return value from the `finally` handler is entirely discarded.
|
||||
|
||||
:::note Cancellation
|
||||
As of Promise v4, `Promise:finally` does not count as a consumer of the parent Promise for cancellation purposes.
|
||||
This means that if all of a Promise's consumers are cancelled and the only remaining callbacks are finally handlers,
|
||||
the Promise is cancelled and the finally callbacks run then and there.
|
||||
|
||||
Cancellation still propagates through the `finally` Promise though: if you cancel the `finally` Promise, it can cancel
|
||||
its parent Promise if it had no other consumers. Likewise, if the parent Promise is cancelled, the `finally` Promise
|
||||
will also be cancelled.
|
||||
:::
|
||||
|
||||
```lua
|
||||
|
|
Loading…
Reference in a new issue