Skip to content

Commit 8d7848a

Browse files
committed
support 3rd-party thenables, handle async errors same way as sync
1 parent 0b8fabb commit 8d7848a

File tree

3 files changed

+10
-8
lines changed

3 files changed

+10
-8
lines changed

docs/api/createAsyncThunk.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ const updateUser = createAsyncThunk(
357357

358358
### Canceling Before Execution
359359

360-
If you need to cancel a thunk before the payload creator is called, you may provide a `condition` callback as an option after the payload creator. The callback will receive the thunk argument and an object with `{getState, extra}` as parameters, and use those to decide whether to continue or not. If the execution should be canceled, the `condition` callback should return a literal `false` value or a promise that should resolve to `false` or reject with any value. If a promise is returned, the thunk waits for it to get fulfilled before dispatching the `pending` action, otherwise it proceeds with dispatching synchronously.
360+
If you need to cancel a thunk before the payload creator is called, you may provide a `condition` callback as an option after the payload creator. The callback will receive the thunk argument and an object with `{getState, extra}` as parameters, and use those to decide whether to continue or not. If the execution should be canceled, the `condition` callback should return a literal `false` value or a promise that should resolve to `false`. If a promise is returned, the thunk waits for it to get fulfilled before dispatching the `pending` action, otherwise it proceeds with dispatching synchronously.
361361

362362
```js
363363
const fetchUserById = createAsyncThunk(

packages/toolkit/src/createAsyncThunk.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -554,12 +554,11 @@ If you want to use the AbortController to react to \`abort\` events, please cons
554554
let finalAction: ReturnType<typeof fulfilled | typeof rejected>
555555
try {
556556
let conditionResult = options?.condition?.(arg, { getState, extra })
557-
if (conditionResult instanceof Promise) {
558-
try {
559-
conditionResult = await conditionResult
560-
} catch {
561-
conditionResult = false
562-
}
557+
if (
558+
typeof conditionResult === 'object' &&
559+
typeof conditionResult.then === 'function'
560+
) {
561+
conditionResult = await conditionResult
563562
}
564563
if (conditionResult === false) {
565564
// eslint-disable-next-line no-throw-literal

packages/toolkit/src/tests/createAsyncThunk.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,10 @@ describe('conditional skipping of asyncThunks', () => {
615615
const condition = () => Promise.reject()
616616
const asyncThunk = createAsyncThunk('test', payloadCreator, { condition })
617617
await asyncThunk(arg)(dispatch, getState, extra)
618-
expect(dispatch).toHaveBeenCalledTimes(0)
618+
expect(dispatch).toHaveBeenCalledTimes(1)
619+
expect(dispatch).toHaveBeenLastCalledWith(
620+
expect.objectContaining({ type: 'test/rejected' })
621+
)
619622
})
620623

621624
test('rejected action is not dispatched by default', async () => {

0 commit comments

Comments
 (0)