response.text() and response.json() get "stuck" sometimes
See original GitHub issueMy code more or less does the following, on React Native 0.45:
async function request() {
const result = await fetch(url);
const data = await result.text();
console.log(data);
return data;
}
When running this in Chrome Debugger on the iOS Simulator, the result will get “stuck” sometimes. By that, I mean the first time I call it, it works fine. But the second time I run a request, the data
will not be printed out until something else happens to jiggle the event loop and cause it to return.
If I disable the chrome debugger, things work.
I assume this is related to what people have been complaining about on the prematurely-closed bug https://github.com/facebook/react-native/issues/6679 .
=================
What follows is my attempt at debugging. I won’t promise anything, as I’m not a promise expert, but maybe it helps narrow things down?
The http response data is shuffled into the response.blob
. When text()
or json()
is called, it calls readBlobAsText
to read the blob, and I do see the string successfully loaded and passed around within the promise/setimmediate/core.js
code. Unfortunately, this string doesn’t always make it back to the caller for some reason.
(This might be a red herring, but I see it call handleResolved()
and the equivalent of setImmediate((self, deferred) => tryCallOne(deferred.onFulfilled, self._65 /* body payload */))
, but the anonymous function isn’t actually called immediately…)
And interesting to note, if I edit fetch.js
to disable support.blob
, it also works.
This makes me suspect it has something to do with the text()
function. In most cases, it returns Promise.reject
or Promise.resolve
, but in the case of using blobs, it returns a newly-generated Promise
(from the fileReaderReady
function). My guess is that this probably triggers another level of promise-indirection, that somehow causes it to stall before the event-loop notices it and triggers it to complete.
I’m still quite a newb as to the JSTimers*
code and guts of the promise
code, so this is where the trail goes cold for me. 😦
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:8 (5 by maintainers)
And the modified ES7 form of the above code that also works for me (thanks!):
Just add the setTimeout before you call
json()
ortext()
or anything else that operates onresponse.blob
.As far as the underlying bug, definitely feels like the eventloop “falls asleep” when processing
response.blob
andreadBlobAsText
, instead of recognizing there are still aPromise
on the eventloop to process and return data back to the callers.Just upgraded and ran into this bug. Using @sebandres’ quick hack to force it to complete.