I think this article is comparing apples to oranges.
The promise pattern is not meant to speed up callback-based code, or to eliminate callbacks altogether.
The purpose of a promise is to allow an asynchronous operation to be cancelled. In the old way, there'd be no standard way to cancel something like this,
xhr.get(url, function (data) {
// do something with the data
});
> The purpose of a promise is to allow an asynchronous operation to be cancelled.
It's not, and the javascript Promise/A spec has no such facility.
Promises — at least in javascript which is the language observed here — are used to return asynchronous results and be able to combine them in various manners (chain, multiplex, select), but not to cancel them.
The purpose of promises in javascript is very much to improve upon callbacks-based systems in order to make them easier to understand and reason about, and more composable.
That's a really good point. I hadn't been completely sold on the value of promises over callbacks before, but this seems like a very unambiguous advantage. I can't think of an obvious, clean way to do this with callbacks that doesn't go a long way toward simply re-implementing promises.
I imagine an advocate of core.async would argue that they have a good analog for canceled promises, though, namely closing channels. On the other hand, closed channels will still yield nil when read from; the procedures trying to read from a closed channel would need to check for that.
> I can't think of an obvious, clean way to do this with callbacks that doesn't go a long way toward simply re-implementing promises.
I may be misunderstanding your point, but you could name the callback function, and give the function object itself a "cancel()" method which alters its behavior to do nothing.
Yes, but that doesn't give you a great way to deal with attaching and canceling multiple callbacks simultaneously. If you want to perform several independent asynchronous actions after some other operation finishes, you have to collect them into a single giant callback in one location. And as you mention, the function has to keep track of some piece of mutable state in order to decide whether it's cancelled or not before firing off those operations. So why not give the function a mutable array of asynchronous operations to perform to begin with, which you can then add to at any time? And at that point, you already have a something very close to a promise.
The promise pattern is not meant to speed up callback-based code, or to eliminate callbacks altogether.
The purpose of a promise is to allow an asynchronous operation to be cancelled. In the old way, there'd be no standard way to cancel something like this,
If we have a promise, we can cancel it, By creating a standard promise pattern, you can have any number of heterogeneous asynchronous operations chained or canceled together uniformly.