Update II
It turned out that Microsfot did what was the simplest way to provide Streams for developers, it simply used what was there already, and exposed within the
readystatechange
listener. That's a
great, easy, and pragmatic solution for IE10 and above. I wish other vendors were like IE ... oh, irony!
Update I
Arthur Stolyar, aka
@nekrtemplar, just explained in
his gist why he's also disappointed about fetch.
To cite his words:
I am not a "One particular high-profile JavaScript community member was unconvinced" or a spec's expert. I am a regular JavaScript/Front-end developer and this is how I see it from my point of view.
His technical explanation is even more detailed than mine so I suggest a read.
Chrome Canary is already exposing a fresh new
Fetch API that has been empathized in this
clarification post from
@jaffathecake.
I've promised him I would have written a counter argument on why not everyone, or at least me, did applaud it.
I will try to answer point after point, providing also my point of view but before starting it's obligatory to underline that nobody is trying to block anything but hopefully the entire thing will be rolled out complete and ASAP with all details in.
Events VS Promises
The first provided example in Jake page talks about a
massively improved API. It shows some basic XHR logic I'd like to reproduce under a different light:
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = () => console.log(xhr.response);
xhr.onerror = () => console.log("Booo");
xhr.send();
Above 5 lines of code have been described in the original, not arrow->function, example as
some vomit to mop up 'cause the new thing looks way better:
fetch(url)
.then(r => r.json())
.then(data => console.log(data))
.catch(e => console.log("Booo"))
;
The example ends up in a rather confusing block for ES7, not sure this is a "back to vomit" thing or not ...
(async() => {
try {
var response = await fetch(url);
var data = await response.json();
console.log(data);
} catch (e) {
console.log("Booo")
}
})();
If we talk about lines of code, fetch wins, but if we talk about clarity of intent can I say XHR has the best?
- it's a GET, not a POST, PUT, HEAD, or others, it's clearly and explicitly a GET
- it comes with listeners, meaning it has
onprogress
included for bigger data
- it comes with
.abort()
as explicit intent, and the ability to add an onabort
in order to react
I will come back to the latter point but here we have yet another competition between Events and Promises, when of course Promises, on top of events, can be used to generated simplified APIs, but comparing them is like comparing apples and oranges: Promises and Events are not mutually exclusive patterns, it's the exact contrary: these can be used together, and indeed, being events more suitable for recurring invocation of the same callback during some streaming operation, it's not that we can blame Events to have an ugly API there,
we simply need them.
My point here is that wrapping XHR through a Promise was already possible and it has been done already so this does not seem to be a reason to applaud this latest API, no
clap clap here, I am sorry, not for this.
It isn't done yet
When I've read this part:
What exists in Chrome today doesn't cover the full spec, and the spec doesn't cover all of the planned features. In some cases this is because they haven't been designed yet, in others it's because they're dependent on other in-progress specs.
I could not help myself thinking about a tweet of mine, posted few days ago:
@dfkaye what I think is that first few lines of any new proposed Standards body API should be about "what real-world problem is this solving"
So I'd like to understand if new APIs just come out "
because" or if there are real reasons behind for pushing these out.
I am 100% sure that
WHATWG does its best, it works hard as a group, and the aim is to provide top notch solutions for our daily needs, but honestly ... to quickly answer to the following Jake disappointment:
Bit of a rant: it bothers me that as developers, we preach iterative development and release, but when we're the customers of that approach the reaction is all too often "HOW DARE YOU PRESENT ME WITH SUCH INCOMPLETE IMPERFECTION".
The way I felt about this was rather like the following: (which is just a satiric parody in my mind)
- Some guru at WHATWG: we need a better version of XHR
- Her colleague: Totally, how should we start?
- Some guru at WHATWG: let's think about a simplified entry-point API to start with
- Her colleague: Totally, gotta Fetch em'all via Promises!!!
- Some guru at WHATWG: well, actually something that .. you know ... Network, something cancelable by default ...
- Her colleague: Totally, gotta Fetch em'all via Generators!!!
- Some guru at WHATWG: ... yeah right ... let's stick with the first idea that breaks only the Promises principles in ES6 ... and re-iterate down the road
And again, the way I see that picture is like:
Because the thing has been
planned from the scratch without breaks in mind!
Having the ability to stop a download, a streamed content, or an upload for the wrong image, should have been the very first thing to think about for a new Network based API, riight?
I am simply astonished the entry point for the new XHR replacement has already a somehow limited/broken heart since the beginning and for the entire ES6 era, because as far as I know native Promises cannot be canceled (yet, 'cause they will eventually ... they have to!)
I wonder then if this is really the right way to roll out new APIs ... so that we are forced to rush solutions in order to be able to improve also a core problem in Promise-land?
Where was the announcement that a new Network API based on Promise was coming? Have I missed that? The answer is probably yes, since it's
even in the specification, but then can I say I wasn't again see that coming at all?
Developers VS Standards
To keep answering Jake disappointment, as a developer I want to trust that standard bodies will choose the right tool for the job.
I like all open channels, I like the iterative model, but I don't honestly have time to be the supervisor for everything so my apologies if I haven't read every single thing people paid to write out published.
As a developer, I'd also like to trust standard bodies that if I've learned something already, like the XHR Level 2 API, and if an API has already been updated for a nice to have upgrade as
onload
and
onprogress
were, maybe just a tiny extra update to bring
onstreaming
would have made such API even better and we could have let libraries and wrappers deal with the best approach to
Promisify all the things and implement once de-facto standardized (obligatory mention to
querySelectorAll
indeed).
This is not me complaining about nicer, easier looking APIs, this is me wondering what's the rush about and why so many steps at once as in the Fetch API and everything else around it.
Not All Disappointing After All
I've hopefully explained why at the very beginning I could not believe to my eyes but also thanks to Jake I've understood there are surrounding parts that come somehow for free like
Streams,
readers, no-cors, ServiceWorkers integration ( through events and
addEeventListener
:trollface: ) and more.
I honestly wish Streams where usable directly as row level API and probably that's going to happen or it happened already, and now that I know about all these things around "
just fecth
" I can't wait for all this
to be fully out and not just a little bit, 'cause as it is, it looks Promising (dehihihi) but it's not worth using it yet due limitations, specially on the current initial cancel-ability (partially in or partially buggy here and there).
About XHR: Yes, It Is Still Good!
If we had a time to improve it, that wouldn't be 16 years ago ... that was Microsoft, not
XMLHttpRquest
, so I am not sure why Jake said that in his blogpost since first working drafts seem to be dated
2006.
However, XHR has been revolutionary for the entire Web and it also made eventually people aware of how the internet was working: not everything is a GET, you could PUT, POST, HEAD, and it has been used to create everything cool today about Google services, social networks etc etc.
It's already easy to do what it can do, so I wouldn't say it has been simplified because of a
.then
.
I can also still upload and drop while uploading images in Gmail, or TweetDeck, or somewhere else and entirely through XHR. I can post data, show progress bars, I can fetch JSON and do CORS. I can do pretty much everything but controlling streams ... and you know what? I think XHR deserves a bit of extra respect.
I wouldn't spit on something that is almost 100% consistently adoptable these days and without libraries, when most of the people just used it to GET some JSON and nothing else (reasons Promise like based Ajax calls became popular, most developers use 10% of XHR ability) for the last 10 years.
Accordingly, if there is one thing I absolutely don't like about that post, is the following sentence:
XHR was an ugly baby and time has not been kind to it. It's 16 now. In a few years it'll be old enough to drink, and it's enough of a pain in the arse when it's sober.
Come on Jake, XHR is still amazing, easy as hell to use, and it still has a lot to offer: abortability with optional reaction through listeners, good integration with Form data, progression, multiple listeners so it can notify multiple "chains" and everything else we know and used for the last 16 years indeed. If it was that bad, I am pretty sure it would have disappeared way before, and the Web as we know would have probably been behind ... don't you think?
Cheers