6 ms·
Sounds like a leaky abstraction. Easier to get started with maybe, but woe betide the legion of programmers who make assumptions based on the appearance of sync
by Shog9 11y ago
Sounds like a leaky abstraction. Easier to get started with maybe, but woe betide the legion of programmers who make assumptions based on the appearance of synchronous execution only to be left stranded when those assumptions don't hold.
Asynchronous execution isn't an unfortunate design choice to be papered over; better to make it as easy as possible to learn and work with.
- radiospiel 11y agoI am not calling to ignoring the async nature of computing in general, I am calling for better tooling. The Linux (and other OS'es) kernel handles I/O asynchronously, yet processes using open(2) + friends work quite well and are usually written in synchronous style. That the actual asyncness is hidden in kernel space does in general not lead to bad programs; and whoever needs async in the space of a single process can still use async tools provided by the kernel when needed. That tooling is much better as it leads to simpler code. I don't see ES7's async support being there yet. Elixir, Go, a number of others: much more.
- Shog9 11y agoApples and oranges. You're describing a platform where it's considered acceptable for programs to block on IO and jump through hoops in rare cases where that's absolutely not ok. A set of assumptions that maybe still made sense 30 years ago, and also a leaky abstraction, but one we've become accustom to working around. If you want that in JavaScript, you can have it; promises were created on the assumption that asynchronous logic is desirable as a matter of course.
- anonymoushn 11y agoWhat are you going to do in Javascript, though, if the I/O takes some time to happen? In golang or lua or whatever I can say "this execution context should block on the I/O for x seconds, then give up and return an error." (the other tens of thousands of execution contexts can keep going) In Javascript I would probably do... the same thing? But I would do it using promises?
- Osiris 11y agoSome Promise library add support for things like `.timeout` so you can force a promise to reject if the promise takes too long to resolve. In cases like a node.js server, Promises allow a single node instance to handle thousands of concurrent requests because the event loop isn't blocking waiting for a single IO request to complete, the process can happily do lots of other things while Promises are pending.
- anonymoushn 11y agoYes, I expect Promise libraries to support timeouts. So it's right that promises allow me to do the same thing I would do with sequential code in other languages? If I had the option of using coroutines when would I choose to use promises? Edit: I'm asking because the context of this thread is that one person said that sequential APIs for asynchronous operations, such as open(2), are pretty nice, and someone else said no they're not pretty nice and we should explicitly deal with the asynchronous nature of operations like open(2) by NOT writing sequential code there.
- Shog9 11y agoIf you have promises OR you have coroutines, your life is good. Either way, you don't have to choose between writing fragile sequential code and writing error-prone synchronization logic. If you don't have either, then you'll probably end up re-implementing one or the other eventually anyway.
- SerpentJoe 11y agoYou can do something like this (using Bluebird's Promise.delay for convenience): // using Promise.race so whoever finishes first wins var fetchingWithTimeout = Promise.race([ // first promise: actually try to perform the computation fetching, // second promise: wait x seconds, then reject Promise.delay(x*1000).then(Promise.reject('Timed out')), ]); You can apply the timeout wherever you want (or apply different timeouts in different corners of the app) without throwing out the raw promise to perform the computation no matter the time cost.
- Matthias247 11y agoImho in this area there is really no general good solution: Either you use the leaky blocking IO abstraction over the async IO - and you will require multiple threads/tasks for doing anything more complicated and lots of complex synchronization. Or you use the async APIs directly and need to work with callbacks/promises/etc., but you can at least avoid synchronization. I personally prefer the async solution, and I think async/await is a good solution to make async code a little more readable.
- rdtsc 11y ago> Either you use the leaky blocking IO abstraction over the async IO What do you mean the leaky blocking IO. It is the non-blocking IO that is leaky, isn't it. If at the business logic there is a request being processed that needs to go through steps a,b,c and then return. b, can't be done unless a finishes and c unless b finishes is mapped pretty cleanly to an execution context of a thread/actor/goroutine/task/process. Shoving IO callback functions in between handling the steps, or spreading them across callbacks or using promises is leaking the abstraction of the platform not being able to handle concurrent processing very well.
- Matthias247 11y agoWhat I meant is that blocking IO is a leaking abstraction, because IO is always asynchronous. What blocking does is adding an extra step (start the process AND waiting for the result) and thereby hiding something. I agree that if you have some pure linear steps (do A, then do B, then do C, and probably use the result from the last step for the next), then the synchronous abstractions work fine. But as soon as you add various timeouts, different error handling strategies, multicast communication, cancellation and other stuff to your async IO procesing then it isn't purely linear anyway. I often end up implementing quite complex state machines for heavy IO related code, and for this I am more happy with working in an asynchronous single-threaded environment.
- deleted 11y ago[deleted]