- From: Jake Archibald <jaffathecake@gmail.com>
- Date: Thu, 21 Aug 2014 10:02:11 +0100
- To: WHATWG <whatwg@whatwg.org>
Over in ServiceWorkerLand we've been getting stuck on the interaction between methods that read a request/response body and the underlying stream. The question was "Should methods that read the body consume it, meaning nothing else can read it?" https://github.com/slightlyoff/ServiceWorker/issues/372#issuecomment-51045111 http://jakearchibald.com/2014/reading-responses/ Both developers & those working on ServiceWorker were pretty split, but we think the "consume" model is the right model, because: * it doesn't regress on the memory usage of XHR (if responseType is json, you can't get the original text) * if you read the stream twice it'll fail, that may be surprising at first, but it fails in your dev environment. If we need to buffer original data for potential later rereads, you can get into memory issues and these will likely show up on particular devices in production * fits in well with streaming models Fetch could change a bit to make this easier to understand & deal with: * response.body should be removed until streams arrive * The as* methods should be directly on the response, and named consumeAs*, so response.consumeAsJSON() * response.consumed (read-only) is true once the body stream has been claimed by a reader * response.clone() creates a clone of the response that can be consumed independently, this is your opt-in to potential buffering * Calling response.clone() on a consumed response creates another consumed response * If a body-reading method is given a response where response.consumed == true, it should throw/reject * Any method that wishes to read the body of the response must cause response.consumed to become true synchronously - we must be consistent with this * Methods that may read the body multiple times must still mark the response as consumed. The clones they create are for internal use only * postMessageing a response will cause it to be cloned, the original remains unconsumed The above is true for request too. So fetch(request) would synchronously mark the request as consumed, even though fetch creates clones or tees internally. This allows developers to duplicate the stream if they need to and send one response to the cache and another to the browser for rendering, you'll get some buffering if one consumer is faster than the other. For the general case of read-once, no buffering is required.
Received on Thursday, 21 August 2014 09:02:37 UTC