Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guest271314/74d3a2aa765330163eecc46e16a52acd to your computer and use it in GitHub Desktop.
Save guest271314/74d3a2aa765330163eecc46e16a52acd to your computer and use it in GitHub Desktop.
const o = {
value: new Map,
done: false,
async * gen(...props) {
while (!this.done) {
if (this.value.size && !this.done) {
try {
for (const [key, val] of this.value) {
// yield* [{key, value: await Promise.all([].concat(val).map(prop => typeof prop === "function" ? prop() : prop)).then(values => { this.value.delete(key); return values }).catch(err => {console.log(err); return {error:[key, err]}})}];
// does not interrupt immediately when `this.done` is set to `true`
for await (const value of [].concat(val).map(prop => Promise.resolve(typeof prop === "function" ? prop() : prop).then(prop => {console.log("prop:", prop); return prop}, err => {
console.error("caught at for await:", err); return err;
}))) {
console.log("value:", value);
if (key !== undefined && value !== undefined && !o.done)
yield * [{
key, value
}];
}
this.value.delete(key);
}
} catch (error) {
console.error("caught at async:", error);
throw error
}
} else {
// yield await `no value at ${new Date()}`;
this.done = true;
break;
}
}
}
};
(async() => {
let n = 0;
let caught, gen;
try {
gen = o.gen();
next = new Proxy(o.value.set.bind(o.value), {
apply(target, _, args) {
// console.log(args);
if (!o.done && args.length) {
Reflect.apply(target, null, args);
return gen.next().catch(err => {
throw err
})
};
if (!args.length && !o.done) return gen.next().catch(err => Promise.reject(err));
if (o.done) {
caught = "we're done here";
return gen.throw(caught).catch(err => {throw err})
};
}
});
// usage
await next(n, Promise.resolve(0)).catch(err => {
throw err
})
.then(({
value, done
}) => console.log(value, done));
await next(++n, Promise.resolve(1))
.catch(err => {
throw err
})
.then(({
value, done
}) => console.log(value, done));
await next(++n, [Promise.resolve(2)])
.catch(err => {
throw err
})
.then(({
value, done
}) => console.log(value, done));
await next(++n, [() => new Promise(r => setTimeout(r, 2000, 3))
, () => new Promise((_, reject) => setTimeout(_, 6000, 4))
, () => new Promise(r => setTimeout(r, 4000, 5))
]
)
.catch(err => {
throw err
})
.then(({
value, done
}) => console.log(value, done));
// o.done = true; // stop generator
while (o.value.size && !o.value.done) {
await next()
.catch(err => {
throw err
}).then(({
value, done
}) => {
console.log(value, done, o.value.size);
return
})
}
} catch (e) {
let message = await e;
if (message === "we're done here") {
console.error("err:", message);
} else {
console.error("caught at catch:", message);
throw new Error(message)
}
} finally {
console.log(gen);
if (caught) throw new Error(caught)
return {done: o.done, value: o.value.size}
}
})()
.catch(err => { console.error("ok caught:", err); return err})
.then(done => console.log("done:", done));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment