-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Wrote some code in #48 that was like:
function map(iterable, fn) {
return new Repeater(async (push, stop) => {
const iter = iterable[Symbol.asyncIterator]();
let finalIteration;
stop.then(() => {
finalIteration = typeof iter.return === "function" ? iter.return() : {done: true};
});
while (!finalIteration) {
const iteration = await iter.next();
if (iteration.done) {
stop();
return iteration.value;
}
await push(fn(iteration.value));
}
// there’s no need to return finalIteration’s value here because when repeaters are returned, the return value will just be whatever was passed into the `return` method.
await finalIteration;
});
}Note that we have to call stop manually before performing an early return in the repeater executor (stop(); return;). I’m starting to think that the stop could just be implicit when we return from the executor.
We automatically stop the executor when the repeater execution rejects or throws, so why don’t we automatically stop the executor when it returns or fulfills? I think I initially did not implement repeaters in this way because of tests where I would push in a sync function, but I have never written any actual real-life repeaters which don’t await stop somehow.
This would be a breaking change. It would require people who returned early from repeaters to await stop, but I’m not sure anyone uses repeaters like that.