Skip to content

Commit

Permalink
implement AbortController stub for node, react native & IE
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Mar 4, 2020
1 parent b1f66ea commit 41faf00
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
44 changes: 44 additions & 0 deletions src/createAsyncThunk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import {
import { configureStore } from './configureStore'
import { AnyAction } from 'redux'

import {
mockConsole,
createConsole,
getLog
} from 'console-testing-library/pure'

describe('createAsyncThunk', () => {
it('creates the action types', () => {
const thunkActionCreator = createAsyncThunk('testType', async () => 42)
Expand Down Expand Up @@ -408,4 +414,42 @@ describe('createAsyncThunk with abortController', () => {
meta: { aborted: true }
})
})

describe('behaviour with missing AbortController', () => {
let keepAbortController: typeof AbortController
let freshlyLoadedModule: typeof import('./createAsyncThunk')
let restore: () => void

beforeEach(() => {
keepAbortController = window.AbortController
delete window.AbortController
jest.resetModules()
freshlyLoadedModule = require('./createAsyncThunk')
restore = mockConsole(createConsole())
})

afterEach(() => {
restore()
window.AbortController = keepAbortController
jest.resetModules()
})

test('calling `abort` on an asyncThunk works with a FallbackAbortController if no global abortController is not available', async () => {
const longRunningAsyncThunk = freshlyLoadedModule.createAsyncThunk(
'longRunning',
async () => {
await new Promise(resolve => setTimeout(resolve, 30000))
}
)

store.dispatch(longRunningAsyncThunk()).abort()
// should only log once, even if called twice
store.dispatch(longRunningAsyncThunk()).abort()

expect(getLog().log).toMatchInlineSnapshot(`
"This platform does not implement AbortController.
If you want to use the AbortController to react to \`abort\` events, please consider importing a polyfill like 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'."
`)
})
})
})
30 changes: 29 additions & 1 deletion src/createAsyncThunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,34 @@ export function createAsyncThunk<
}
)

let displayedWarning = false

const AC =
typeof AbortController !== 'undefined'
? AbortController
: class implements AbortController {
signal: AbortSignal = {
aborted: false,
addEventListener() {},
dispatchEvent() {
return false
},
onabort() {},
removeEventListener() {}
}
abort() {
//if (process.env.NODE_ENV === 'development') {
if (!displayedWarning) {
displayedWarning = true
console.info(
`This platform does not implement AbortController.
If you want to use the AbortController to react to \`abort\` events, please consider importing a polyfill like 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'.`
)
}
//}
}
}

function actionCreator(arg: ThunkArg) {
return (
dispatch: GetDispatch<ThunkApiConfig>,
Expand All @@ -175,7 +203,7 @@ export function createAsyncThunk<
) => {
const requestId = nanoid()

const abortController = new AbortController()
const abortController = new AC()
let abortReason: string | undefined

const abortedPromise = new Promise<never>((_, reject) =>
Expand Down

0 comments on commit 41faf00

Please sign in to comment.