@@ -120,12 +120,16 @@ class Fetch extends EE {
120
120
}
121
121
}
122
122
123
+ function handleFetchDone ( response ) {
124
+ finalizeAndReportTiming ( response , 'fetch' )
125
+ }
126
+
123
127
// https://fetch.spec.whatwg.org/#fetch-method
124
128
function fetch ( input , init = undefined ) {
125
129
webidl . argumentLengthCheck ( arguments , 1 , 'globalThis.fetch' )
126
130
127
131
// 1. Let p be a new promise.
128
- const p = createDeferredPromise ( )
132
+ let p = createDeferredPromise ( )
129
133
130
134
// 2. Let requestObject be the result of invoking the initial value of
131
135
// Request as constructor with input and init as arguments. If this throws
@@ -185,16 +189,17 @@ function fetch (input, init = undefined) {
185
189
// 3. Abort controller with requestObject’s signal’s abort reason.
186
190
controller . abort ( requestObject . signal . reason )
187
191
192
+ const realResponse = responseObject ?. deref ( )
193
+
188
194
// 4. Abort the fetch() call with p, request, responseObject,
189
195
// and requestObject’s signal’s abort reason.
190
- abortFetch ( p , request , responseObject , requestObject . signal . reason )
196
+ abortFetch ( p , request , realResponse , requestObject . signal . reason )
191
197
}
192
198
)
193
199
194
200
// 12. Let handleFetchDone given response response be to finalize and
195
201
// report timing with response, globalObject, and "fetch".
196
- const handleFetchDone = ( response ) =>
197
- finalizeAndReportTiming ( response , 'fetch' )
202
+ // see function handleFetchDone
198
203
199
204
// 13. Set controller to the result of calling fetch given request,
200
205
// with processResponseEndOfBody set to handleFetchDone, and processResponse
@@ -228,10 +233,11 @@ function fetch (input, init = undefined) {
228
233
229
234
// 4. Set responseObject to the result of creating a Response object,
230
235
// given response, "immutable", and relevantRealm.
231
- responseObject = fromInnerResponse ( response , 'immutable' )
236
+ responseObject = new WeakRef ( fromInnerResponse ( response , 'immutable' ) )
232
237
233
238
// 5. Resolve p with responseObject.
234
- p . resolve ( responseObject )
239
+ p . resolve ( responseObject . deref ( ) )
240
+ p = null
235
241
}
236
242
237
243
controller = fetching ( {
@@ -314,7 +320,10 @@ const markResourceTiming = performance.markResourceTiming
314
320
// https://fetch.spec.whatwg.org/#abort-fetch
315
321
function abortFetch ( p , request , responseObject , error ) {
316
322
// 1. Reject promise with error.
317
- p . reject ( error )
323
+ if ( p ) {
324
+ // We might have already resolved the promise at this stage
325
+ p . reject ( error )
326
+ }
318
327
319
328
// 2. If request’s body is not null and is readable, then cancel request’s
320
329
// body with error.
@@ -1066,7 +1075,10 @@ function fetchFinale (fetchParams, response) {
1066
1075
// 4. If fetchParams’s process response is non-null, then queue a fetch task to run fetchParams’s
1067
1076
// process response given response, with fetchParams’s task destination.
1068
1077
if ( fetchParams . processResponse != null ) {
1069
- queueMicrotask ( ( ) => fetchParams . processResponse ( response ) )
1078
+ queueMicrotask ( ( ) => {
1079
+ fetchParams . processResponse ( response )
1080
+ fetchParams . processResponse = null
1081
+ } )
1070
1082
}
1071
1083
1072
1084
// 5. Let internalResponse be response, if response is a network error; otherwise response’s internal response.
@@ -1884,7 +1896,11 @@ async function httpNetworkFetch (
1884
1896
// 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s
1885
1897
// controller with reason, given reason.
1886
1898
const cancelAlgorithm = ( reason ) => {
1887
- fetchParams . controller . abort ( reason )
1899
+ // If the aborted fetch was already terminated, then we do not
1900
+ // need to do anything.
1901
+ if ( ! isCancelled ( fetchParams ) ) {
1902
+ fetchParams . controller . abort ( reason )
1903
+ }
1888
1904
}
1889
1905
1890
1906
// 13. Let highWaterMark be a non-negative, non-NaN number, chosen by
0 commit comments