20:26 | <sirisian> | Does anyone know if the iterator helper proposal has ever discussed parallel/batch features for v1? A lot of my use cases for lazy iterators involve async operations that benefit from parallel requests. Maybe I'm thinking of this wrong, but like for (const item of webpages.map(async url => return await op(url), { batch: 5 })){} where 5 are executed in parallel and are handled out of order first come. (In theory if a break is called then the other 4 pending would be cancelled by the generator's return). The big picture is handling tasks that might look like [500ms, 10ms, 10ms, 10ms, 10ms...] where a random long task blocks the whole pipeline. With more complex pipelines this snowballs into large delays. |
20:48 | <bakkot> | sirisian: not for v1, no. I would also like to see such a thing at some point but it doesn't really fit with the simpler v1 helpers; it would be its own thing |
20:48 | <sirisian> | As long as it's possible later, that's all that matters. |
20:49 | <bakkot> | I haven't thought about it really hard but I expect it should be. and at the very least nothing in this proposal is likely to make it harder. |
20:50 | <Ashley Claymore> | Ixjs has this with a concurrent param for flatMap https://github.com/ReactiveX/IxJS/blob/master/src/asynciterable/operators/flatmap.ts |
21:02 | <bakkot> | for the particular example you give I think the thing you actually want is a helper to bound how many invocations of an async function can be running simultaneously |
21:07 | <bakkot> |
|
21:07 | <bakkot> | or something to that effect |
21:07 | <bakkot> | so you can do .map(boundAsyncFunctionConcurrency(async url => await op(url), 5)) |
21:08 | <bakkot> | rather than getting the iterator helpers involved directly |
21:08 | <bakkot> | but there are probably other cases where you'd want the iterator helpers to be involved |
21:55 | <Domenic> | I've used https://www.npmjs.com/package/throat in the past |
22:57 | <sirisian> | bakkot: Wouldn't your implementation instantly create N promises consuming the whole input generator? Ideally a lazy iterator implementation wouldn't do that. The map would only call next 5 times to start then again when the first promise returns. Ideally a generator could have infinite items and everything would just work. |
23:34 | <bakkot> | sirisian: no, it will not consume the whole input |
23:34 | <bakkot> | not unless you toArray it or something, anyway |
23:36 | <bakkot> | iterator helpers are lazy |
23:36 | <bakkot> | which, it occurs to me, probably means they're not a good fit for what you're trying to do anyway |
23:38 | <bakkot> | you can't really have all three of "works with infinite generators", "provides results in order", and "does not block on inputs which are slow" |
23:41 | <bakkot> | because if you don't block on slow inputs, but you still want to get results in order, that means it has to eagerly start doing work for results past the next one, which means it's not going to work for infinite iterators. |
23:41 | <sirisian> | Well I said out of order. |
23:41 | <bakkot> | ohh, missed that |
23:41 | <bakkot> | I don't think we want iterators to ever provide results out of order, so that would just be a different proposal for a different mechanism entirely |
23:43 | <sirisian> | I do see what you mean though. In applications where order matters batch means something very different than what I intended in my ad-hoc example. |
23:44 | <bakkot> | I think the thing you want is something which works with sync iterators which yield promises? Let me see... |