7 ms·
Show HN: Axax – Async iterator extensions for JavaScript
- scanr 8y agoAuthor here. Happy to answer any questions.
- k__ 8y agoNice work! Reminds me of callbags, but for async/await hehe
- scanr 8y agoThanks! Someone else showed me callbags just today. Looks great.
- smg 8y agoGreat work! From the presentation by Benjamin Gruenbaum - `Why Async Iterators Matter` there is slide where he shows how some Rxjs code can be rewritten using async iterators. https://docs.google.com/presentation/d/1r2V1sLG8JSSk8txiLh4wfTkom-BoOsk52FgPBy8o3RM/edit#slide=id.g1236b1e2d6_0_314 https://docs.google.com/presentation/d/1r2V1sLG8JSSk8txiLh4w... Is there a chance we could see some more examples of complicated Rxjs patterns being replaced by code using Axax?
- scanr 8y agoWould love to. Do you know where I could find some in the wild? They often help inform what functions to add to axax.
- smg 8y agoHere are some Rxjs examples from an older version of the library https://github.com/Reactive-Extensions/RxJS/tree/master/examples https://github.com/Reactive-Extensions/RxJS/tree/master/exam...
- crooked-v 8y agoAny chance of adding a wrapper for async iterables that allows chaining of filter, map, etc rather than needing to individually import each function? Similarly, a forEach would be welcome for those of us who prefer to avoid for loops.
- scanr 8y agoThanks for your suggestions. Chaining would be neat. For each should be pretty simple to do.
- crooked-v 8y agoFor other stuff, anything from lodash or ramda that could reasonably be applied to async iterables would be welcome, possibly with some tweaks. For example, a `find` method that returns a Promise that resolves with the first matching result, or optionally rejects after X milliseconds timeout, or a `reduce` that returns an iterable that returns each new reducer result.
- johnny_reilly 8y agoGreat work! (And hey I'm biased; I have contributed to this project) It's clear this project has some overlap with the sort of problems that make many people reach for rxjs. What would make you use this project in place of rxjs in those situations?
- scanr 8y agoThanks, John! And thanks for contributing. I find that their are async problems where it’s easier to reason about control flow using async iterators vs observables. This slideshow (link provided by @smg) does a great job of explaining when async iterators can be useful vs rx: https://docs.google.com/presentation/d/1r2V1sLG8JSSk8txiLh4wfTkom-BoOsk52FgPBy8o3RM/mobilepresent?slide=id.p https://docs.google.com/presentation/d/1r2V1sLG8JSSk8txiLh4w...
- Waterluvian 8y agoSo I finally took the time to learn `async await` the other day. Holy cow does it clean up my promises. One thing that burned me bad though was that without a `try` anywhere, my 100 line async function failed silently. I think because its transpiling to promises and nothing was handling a failed returned promise. Really really frustrating. Anywho, I appreciate that there's lots of more complex things one wants to do with async iteration. But I often see these complex examples that use all kinds of neat features that I probably don't need to be bothered with. I don't want to set up pipes and such, I just want to give a collection, a function, and get the result in an async function. I want this: let result = await map(collection, expensiveFunction); How would this be done with Axax? And I guess the point of my feedback: you chums are experts with this stuff. You wrote the library. Don't forget the "step stool" examples to help newbies get into the library, too!
- chrismorgan 8y agoNo need to get any extra library involved; the standard library handles your case: let result = await Promise.all(collection.map(expensiveFunction)); (I’m presuming expensiveFunction is an asynchronous function; if it is instead a synchronous function, then don’t bother about the Promise.all part, just do it all at once asynchronously, as the effect will be the same: `new Promise(resolve => setTimeout(() => resolve(collection.map(expensiveFunction))))`.)
- arilotter 8y agoYour last snippet only defers the code execution to the next iteration of the event loop. If it's synchronous, Since it's "blocking" anyways (no IO or network requests), why not just `let result = collection.map(expensiveFunction)` ?
- dvlsg 8y agoYou could toss the expensive function in a web worker to make it non blocking.
- 8y ago
- erdaniels 8y agoHow much of this is already satisfied by ES2018 async iterstors? Either way it's nice to see it already exist in a pure format.
- girvo 8y agoI guess fromEvent and the Subject class aren’t, and being able to know that any Subject can be operated on with this admittedly nice function set without issues is a boon above and beyond ES2018 async iterators, I feel
- scanr 8y agoThis is just a number of utility functions I found useful to use on top of async iterators. The great thing about async iterators is that the implementation for a lot of these is relatively simple.
- erdaniels 8y agoIndeed. Yeah this is very nice. Great work!
- girvo 8y agoI’ve been looking for something like this for a while; a nice well thought out interface for async iterators that is simple to integrate into any given event system. I quite like the `fromEvent` function and `Subject` class: they should make it really easy to achieve what I’ve been after, without me writing yet another set of boilerplate interfaces around a stream!
- ThJ 8y agoThis is more or less what RxJS calls an Observable (except with nicer syntax). Here's a very nice table that makes the lack of this feature in ESnext seem like a strange omission: https://danreynolds.ca/images/tech/push-pull.png https://danreynolds.ca/images/tech/push-pull.png Asynchronous iterators / observables are so much more useful that synchronous iterators that they should've added that to the standard first. Wouldn't it be wonderful if ESnext allowed you to write event loops that maintain state with block scope variables instead of all the hacks we have to resort to now? EDIT: RxJS is mentioned in the README. What I like about this is that it doesn't try to implement the kitchen sink and is a fairly atomic dependency. Now if we could just get to where we don't need transpilers anymore, that would be nice.
- CGamesPlay 8y agoIn case that link is your site, the SSL hostname is for `www.` not for the main domain, so it doesn't load in Safari. Chrome for whatever reason didn't care.
- abraham 8y agoChrome shows an interesting notice in the console. > Redirecting navigation danreynolds.ca -> www.danreynolds.ca because the server presented a certificate valid for www.danreynolds.ca but not for danreynolds.ca. To disable such redirects launch Chrome with the following flag: --disable-features=SSLCommonNameMismatchHandling
- ThJ 8y agoIt's not my site. Just didn't bother to hunt for that image in the RxJS docs and looked for it on GIS instead, since I was on a phone.
- tzahola 8y ago>Wouldn't it be wonderful if ESnext allowed you to write event loops that maintain state with block scope variables instead of all the hacks we have to resort to now? I think this is already possible: let event = null while (event = await getNextEvent()) { ... // process event } getNextEvent() creates a promise, registers an event handler which resolves it and returns the promise. Have I misunderstood your question?
- mabynogy 8y agoIt's nice. I do that with generators in my programming language. let* choice from_confirm "Yes or No?" This code will create a loop over the generator function form_confirm(). It behaves like if it was blocking.
- bthornbury 8y agoWhat advantage does this have over enumerating the iterable and using the regular `map` and other such calls. In my mind, I'm thinking this creates something like a chain of generators in python, but would love if someone could explain in JS terms.