bugfix (Chromium issue 1361981) + reworked generator promise API (.then(..) -> .unwind(..))...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-09-14 11:22:00 +03:00
parent ccbc4ab48e
commit a60443e3ec
3 changed files with 35 additions and 19 deletions

View File

@ -111,6 +111,7 @@ Library of JavaScript type extensions, types and utilities.
- [`<generator>.shift()` / `<generator>.pop()` / `<generator>.gshift()` / `<generator>.gpop()`](#generatorshift--generatorpop--generatorgshift--generatorgpop)
- [`<generator>.unshift(..)` / `<generator>.push(..)`](#generatorunshift--generatorpush)
- [`<generator>.join(..)`](#generatorjoin)
- [`<generator>.unwind(..)`](#generatorunwind)
- [`<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally)
- [`<generator>.toArray()`](#generatortoarray)
- [Treating iterators the same as generators](#treating-iterators-the-same-as-generators)
@ -124,7 +125,7 @@ Library of JavaScript type extensions, types and utilities.
- [`<Generator>.between(..)`](#generatorbetween-1)
- [`<Generator>.toArray()`](#generatortoarray-1)
- [`<Generator>.join(..)`](#generatorjoin-1)
- [`<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)`](#generatorthen--generatorcatch--generatorfinally-1)
- [`<Generator>.unwind(..)`](#generatorunwind-1)
- [Generator combinators](#generator-combinators)
- [`<Generator>.chain(..)` / `<generator>.chain(..)`](#generatorchain--generatorchain)
- [`<Generator>.concat(..)` / `<generator>.concat(..)`](#generatorconcat--generatorconcat)
@ -136,6 +137,7 @@ Library of JavaScript type extensions, types and utilities.
- [`generator.stoppable(..)`](#generatorstoppable)
- [Async generator extensions](#async-generator-extensions)
- [`generator.AsyncGenerator`](#generatorasyncgenerator)
- [`<async-generator>.unwind(..)`](#async-generatorunwind)
- [`<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`](#async-generatorthen--async-generatorcatch--async-generatorfinally)
- [`<async-generator>.iter(..)`](#async-generatoriter)
- [`<async-generator>.map(..)` / `<async-generator>.filter(..)` / `<async-generator>.reduce(..)`](#async-generatormap--async-generatorfilter--async-generatorreduce)
@ -2292,6 +2294,11 @@ _next_ call to `.next()`, regardless of the current generator state.
XXX
#### `<generator>.unwind(..)`
XXX
#### `<generator>.then(..)` / `<generator>.catch(..)` / `<generator>.finally(..)`
Return a promise and resolve it with the generator value.
@ -2513,7 +2520,7 @@ Return a function that will return a `<generator>` output as an `Array`.
XXX
#### `<Generator>.then(..)` / `<Generator>.catch(..)` / `<Generator>.finally(..)`
#### `<Generator>.unwind(..)`
<!-- XXX -->
@ -2641,6 +2648,8 @@ XXX EXPERIMENTAL
#### `generator.AsyncGenerator`
#### `<async-generator>.unwind(..)`
#### `<async-generator>.then(..)` / `<async-generator>.catch(..)` / `<async-generator>.finally(..)`
#### `<async-generator>.iter(..)`

View File

@ -189,11 +189,11 @@ var makeGenerator = function(name, pre){
].join('\n ') }, }) } }
// XXX do a better doc...
var makePromise = function(name){
var makeProxy = function(name){
return function(...args){
var that = this
return function(){
return that(...arguments)[name](func) } } }
return that(...arguments)[name](...args) } } }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -267,9 +267,12 @@ object.Mixin('GeneratorMixin', 'soft', {
// promises...
//
then: makePromise('then'),
catch: makePromise('catch'),
finally: makePromise('finally'),
// NOTE: .then(..) and friends are intentionally not defined here to
// prevent control deadlocks when awaiting for a generator that
// expects manual unwinding e.g.:
// g = function*(){}
// await g // will hang waiting for g to resolve
unwind: makeProxy('unwind'),
// combinators...
//
@ -450,7 +453,8 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
// promises...
//
then: function(onresolve, onreject){
// NOTE: this will unwind the generator...
unwind: function(onresolve, onreject){
var that = this
var p = new Promise(
function(resolve){
@ -459,10 +463,12 @@ object.Mixin('GeneratorProtoMixin', 'soft', {
p.then(...arguments)
: p
return p },
then: function(...args){
return this.unwind(...args) },
catch: function(func){
return this.then().catch(func) },
return this.unwind().catch(...arguments) },
finally: function(func){
return this.then().finally(func) },
return this.unwind.finally(...arguments) },
// combinators...
//
@ -531,22 +537,23 @@ object.Mixin('AsyncGeneratorProtoMixin', 'soft', {
//
// NOTE: this will unwind the generator...
// XXX create an iterator promise???
// XXX should we unwind???
then: function(resolve, reject){
unwind: function(onresolve, onreject){
var that = this
var p = new Promise(async function(_resolve, _reject){
var p = new Promise(async function(resolve){
var res = []
for await(var elem of that){
res.push(elem) }
_resolve(res) })
p = (resolve || reject) ?
resolve(res) })
p = (onresolve || onreject) ?
p.then(...arguments)
: p
return p },
then: function(...args){
return this.unwind(...args) },
catch: function(func){
return this.then().catch(func) },
finally: function(){
return this.then().finally(func) },
return this.unwind().catch(...arguments) },
finally: function(func){
return this.unwind.finally(...arguments) },
// XXX might be a good idea to use this approach above...
iter: stoppable(async function*(handler=undefined){

View File

@ -1,6 +1,6 @@
{
"name": "ig-types",
"version": "6.19.0",
"version": "6.20.0",
"description": "Generic JavaScript types and type extensions...",
"main": "main.js",
"scripts": {