@@ -238,18 +238,17 @@ export function processReply(
238
238
// Upgrade to use FormData to allow us to stream this value.
239
239
formData = new FormData ( ) ;
240
240
}
241
+ pendingParts ++ ;
241
242
try {
242
243
const resolvedModel = init ( payload ) ;
243
244
// We always outline this as a separate part even though we could inline it
244
245
// because it ensures a more deterministic encoding.
245
- pendingParts ++ ;
246
246
const lazyId = nextPartId ++ ;
247
247
const partJSON = JSON . stringify ( resolvedModel , resolveToJSON ) ;
248
248
// $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
249
249
const data : FormData = formData ;
250
250
// eslint-disable-next-line react-internal/safe-string-coercion
251
251
data . append ( formFieldPrefix + lazyId , partJSON ) ;
252
- pendingParts -- ;
253
252
return serializeByValueID ( lazyId ) ;
254
253
} catch ( x ) {
255
254
if (
@@ -261,35 +260,33 @@ export function processReply(
261
260
pendingParts ++ ;
262
261
const lazyId = nextPartId ++ ;
263
262
const thenable : Thenable < any > = (x: any);
264
- thenable.then(
265
- partValue => {
266
- try {
267
- const partJSON = JSON . stringify ( partValue , resolveToJSON ) ;
268
- // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
269
- const data : FormData = formData ;
270
- // eslint-disable-next-line react-internal/safe-string-coercion
271
- data . append ( formFieldPrefix + lazyId , partJSON ) ;
272
- pendingParts -- ;
273
- if ( pendingParts === 0 ) {
274
- resolve ( data ) ;
275
- }
276
- } catch ( reason ) {
277
- reject ( reason ) ;
263
+ const retry = function() {
264
+ // While the first promise resolved, its value isn't necessarily what we'll
265
+ // resolve into because we might suspend again.
266
+ try {
267
+ const partJSON = JSON . stringify ( value , resolveToJSON ) ;
268
+ // $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
269
+ const data : FormData = formData ;
270
+ // eslint-disable-next-line react-internal/safe-string-coercion
271
+ data . append ( formFieldPrefix + lazyId , partJSON ) ;
272
+ pendingParts -- ;
273
+ if ( pendingParts === 0 ) {
274
+ resolve ( data ) ;
278
275
}
279
- } ,
280
- reason => {
281
- // In the future we could consider serializing this as an error
282
- // that throws on the server instead.
276
+ } catch ( reason ) {
283
277
reject ( reason ) ;
284
- } ,
285
- );
278
+ }
279
+ }
280
+ thenable . then ( retry , retry ) ;
286
281
return serializeByValueID ( lazyId ) ;
287
282
} else {
288
283
// In the future we could consider serializing this as an error
289
284
// that throws on the server instead.
290
285
reject ( x ) ;
291
286
return null ;
292
287
}
288
+ } finally {
289
+ pendingParts -- ;
293
290
}
294
291
}
295
292
}
0 commit comments