Show HN: Axax – Async iterator extensions for JavaScript
github.com
github.com
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.
> 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
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?
Can't you do that with a btree already?
'use strict';
function getNextEvent() {
return new Promise(resolve => {
document.getElementById('button').onclick = event => resolve(event);
})
}
async function enterEventLoop() {
let event = null;
while (event = await getNextEvent()) {
alert(event);
}
}
enterEventLoop();
And thanks for recommending RxJS, but I've been using reactive programming on various platforms for the past 6 years, so I'm pretty sure it already had "clicked" for me.An interesting alternative to the library mentioned here is that IxJS is the RxJS team's own implementation of the sorts of operators that Axax is trying to provide, though for both ordinary iterators and async iterators: https://github.com/ReactiveX/IxJS
IxJS gets the benefits of trying to share as much as possible the same API as RxJS, making it really easy to use bits of IxJS and RxJS in the same project, depending on use case.
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!
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))))`.)Typed arrays can be zero-copy transferred to a worker extremely quickly, modified, then transferred back if needed.
No costly copying or cloning needed. But it won't work with just objects, just typed arrays.
new Promise(resolve => {
const out = [];
const iterator = collection[Symbol.iterator]();
function next() {
const item = iterator.next();
if (item) {
setTimeout(() => {
out.push(expensiveFunction(item.value));
next();
});
} else {
resolve(out);
}
}
next();
});
JavaScript’s threading model is rather hostile to expensive CPU-bound functions. Workers are just too hard to use unless you go all in with that architecture. I love being able to work with things like Rayon in Rust.This is a promise thing, it doesn’t really have to do with async/await or transpiling.
Node.js and some browsers have a warning or event you can listen for https://developer.mozilla.org/en-US/docs/Web/Events/unhandle...
I've played with catchify a bit.
https://github.com/majgis/catchify
https://www.npmjs.com/package/catchify
Feels less awful. But I'm still ambivalent. Callbacks vs promises vs async/await vs catchify's golang style error propagation. Yay.
I intended to weave in timeouts and tracing (metrics). See if that makes nodejs dev work sufferable. Maybe a catchify & timeoutify & traceify hybrid will keep me from playing in traffic.
async function asyncTask(cb) {
async functions return a promise that rejects if an error is thrown (either directly or by a promise that is awaited on), so there’s no need to handle every error if you’re ok with it just propagating.Am I doing something terribly wrong?
You should be bubbling errors up to some top level and at least catching them there.
Wrapping entire async-fn bodies with try/catch (or outright overuse of try/catch) is probably the most ubiquitous beginner mistake I see in modern Javascript.
For example, imagine if your top level was even just run().catch(console.error).
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?
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/1r2V1sLG8JSSk8txiLh4w...
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.
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.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/1r2V1sLG8JSSk8txiLh4w...
Is there a chance we could see some more examples of complicated Rxjs patterns being replaced by code using Axax?
https://github.com/Reactive-Extensions/RxJS/tree/master/exam...
Similarly, a forEach would be welcome for those of us who prefer to avoid for loops.