Last active
April 23, 2020 15:51
-
-
Save guest271314/74d3a2aa765330163eecc46e16a52acd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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