Skip to content

Commit

Permalink
[abort promise] update abort promise
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-diamond committed Apr 12, 2024
1 parent d540f3f commit 7b91fce
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 29 deletions.
9 changes: 9 additions & 0 deletions src/modules/gql-module/abortCallback.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
class AbortCallback {
private isAborted: boolean
callback: Promise<any>
onAbort: () => void

constructor(callback: Promise<any>, onAbort: () => void) {
this.isAborted = false
this.callback = callback
this.onAbort = onAbort
}

then(onSuccess: (data: any) => any, onError?: (error: any) => any) {
if (this.isAborted) {
const dummyPromise = new Promise(() => {})

return new AbortCallback(dummyPromise, this.onAbort)
}

return new AbortCallback(this.callback.then(onSuccess, onError), this.onAbort)
}

Expand All @@ -20,6 +28,7 @@ class AbortCallback {
}

abort() {
this.isAborted = true
this.onAbort()
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/modules/gql-module/abortPromise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ const dummyPromise = new Promise(() => {})
class AbortPromise<Data> {
private promise: Promise<Data>
private isAborted: boolean
private onAbort?: () => void

constructor(callback: AbortPromiseCallback<Data>) {
constructor(callback: AbortPromiseCallback<Data>, onAbort?: () => void) {
this.isAborted = false
this.onAbort = onAbort

this.promise = new Promise(callback)
.then((data) => {
try {
Expand Down Expand Up @@ -58,6 +61,7 @@ class AbortPromise<Data> {
}
})
}

const allPromises = Promise.all(promises).then((data) => {
if (isAborted) {
return dummyPromise as Promise<T[]>
Expand Down Expand Up @@ -95,6 +99,10 @@ class AbortPromise<Data> {

abort() {
this.isAborted = true

if (typeof this.onAbort === 'function') {
this.onAbort()
}
}
}

Expand Down
44 changes: 16 additions & 28 deletions src/modules/gql-module/abortRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AbortCallback from './abortCallback'
import AbortPromise from './abortPromise'


type ModifyCallback<Data, ModifiedData = Data> = (value: Data) => ModifiedData | PromiseLike<ModifiedData>
Expand All @@ -18,14 +18,12 @@ type PendingRequest = {

const requestsQueue: Record<string, PendingRequest | undefined> = {}

const dummyPromise = new Promise(() => {})

// Returns fetch promise that can be aborted
// If we create several promises, only one request will be executed
class AbortRequest<Data, ModifiedData> {
private controller = new AbortController()
request: Promise<Data>
promise: Promise<ModifiedData>
promise: AbortPromise<ModifiedData>
body: string
isAborted: boolean

Expand Down Expand Up @@ -63,42 +61,32 @@ class AbortRequest<Data, ModifiedData> {
}
}

this.promise = this.request
.then((data) => {
try {
if (this.isAborted) {
return dummyPromise as Promise<ModifiedData>
}

if (typeof onSuccess === 'function') {
return onSuccess(data) as Promise<ModifiedData>
}
this.promise = new AbortPromise<ModifiedData>(async (resolve, reject) => {
try {
const result = await this.request

return data as Promise<ModifiedData>
}
catch (error) {
return Promise.reject(error)
}
})
.catch((error) => {
if (this.isAborted) {
return dummyPromise as Promise<ModifiedData>
if (typeof onSuccess === 'function') {
return resolve(onSuccess(result) as ModifiedData)
}

return Promise.reject(error)
})
return resolve(result as ModifiedData)
}
catch (error) {
return reject(error)
}
}, this.abort.bind(this))
}

then(onSuccess: FirstCallback<ModifiedData>, onError?: FirstCallback<ModifiedData>) {
return new AbortCallback(this.promise.then(onSuccess, onError), this.abort.bind(this))
return this.promise.then(onSuccess, onError)
}

catch(callback: FirstCallback<ModifiedData>) {
return new AbortCallback(this.promise.catch(callback), this.abort.bind(this))
return this.promise.catch(callback)
}

finally(callback: EmptyCallback) {
return new AbortCallback(this.promise.finally(callback), this.abort.bind(this))
return this.promise.finally(callback)
}

abort() {
Expand Down

0 comments on commit 7b91fce

Please sign in to comment.