You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Addresses feedback from #10460 It is a bit misleading the way it is
worded currently—so I've updated the verbiage accordingly and provided
code snippets
Copy file name to clipboardExpand all lines: docs/hooks/overview.mdx
+22-7Lines changed: 22 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -87,15 +87,15 @@ The following arguments are provided to the `afterError` Hook:
87
87
|**`collection`**| The [Collection](../configuration/collections) in which this Hook is running against. This will be `undefined` if the hook is executed from a non-collection endpoint or GraphQL. |
88
88
|**`result`**| The formatted error result object, available if the hook is executed from a REST context. |
89
89
90
-
## Async vs. Synchronous
90
+
## Awaited vs. non-blocking hooks
91
91
92
-
All Hooks can be written as either synchronous or asynchronous functions. Choosing the right type depends on your use case, but switching between the two is as simple as adding or removing the `async` keyword.
92
+
Hooks can either block the request until they finish or run without blocking it. What matters is whether your hook returns a Promise.
93
93
94
-
#### Asynchronous
94
+
Awaited (blocking): If your hook returns a Promise (for example, if it’s declared async), Payload will wait for it to resolve before continuing that lifecycle step. Use this when your hook needs to modify data or influence the response. Hooks that return Promises run in series at the same lifecycle stage.
95
95
96
-
If the Hook should modify data before a Document is updated or created, and it relies on asynchronous actions such as fetching data from a third party, it might make sense to define your Hook as an asynchronous function. This way you can be sure that your Hook completes before the operation's lifecycle continues.
96
+
Non-blocking (sometimes called “fire-and-forget”): If your hook does not return a Promise (returns nothing), Payload will not wait for it to finish. This can be useful for side-effects that don’t affect the outcome of the operation, but keep in mind that any work started this way might continue after the request has already completed.
97
97
98
-
Async hooks are run in series - so if you have two async hooks defined, the second hook will wait for the first to complete before it starts.
98
+
**Declaring a function with async does not make it “synchronous.” The async keyword simply makes the function return a Promise automatically — which is why Payload then awaits it.**
99
99
100
100
<Bannertype="success">
101
101
**Tip:** If your hook executes a long-running task that doesn't affect the
@@ -104,9 +104,24 @@ Async hooks are run in series - so if you have two async hooks defined, the seco
104
104
continue processing without waiting for the task to complete.
105
105
</Banner>
106
106
107
-
#### Synchronous
107
+
**Awaited**
108
108
109
-
If your Hook simply performs a side-effect, such as mutating document data, it might be okay to define it synchronously, so the Payload operation does not have to wait for your hook to complete.
109
+
```ts
110
+
const beforeChange =async ({ data }) => {
111
+
const enriched =awaitfetchProfile(data.userId) // Payload waits here
0 commit comments