Good point, if it is about iteration, only `return()` needs to be propagated.
> On 24 Mar 2015, at 23:35, Ron Buckton <[email protected]> wrote: > > Is your goal to wrap a generator, as it seems you are propagating the > exception of the caller by calling iterator.throw(). However, you do not seem > to be propagating the sent value, so the protocol here isn’t fully > implmeneted. > > If you just want to iterate values (and don’t really care about the return > value of the iterable or propagating a thrown exception, you could write: > > ```js > function* take(n, iterable) { > n |= 0; > if (n <= 0) { > return; > } > // let for..of call return() > for (let value of iterable) { > yield value; > if (n-- <= 0) { > return; > } > } > } > ``` > > If you want to support the full communication channel of a generator, you > could write: > > ```js > function* take(n, iterable) { > let iterator = iterable[Symbol.iterator](); > let step = () => iterator.next(); > n |= 0; > // try..finally outside of loop > try { > let sent; > while (n > 0) { > let { value, done } = step(); > if (done) { > return value; > } > n--; > // try..catch local to the yield > try { > sent = yield value; > step = () => iterator.next(sent); > } > catch (e) { > if (typeof iterator.throw === "function") { > step = () => iterator.throw(e); > } > else { > throw e; > } > } > } > } > finally { > if (typeof iterator.return === "function") { > iterator.return(); > } > } > } > ``` > > From: es-discuss [mailto:[email protected] > <mailto:[email protected]>] On Behalf Of Axel Rauschmayer > Sent: Tuesday, March 24, 2015 2:28 PM > To: Bergi > Cc: es-discuss list > Subject: Re: Forwarding `return()` in generators > > Right, it doesn’t look like one needs to know the returned value when > forwarding `return()`. > > But: you need to guard against other ways of reaching `finally`. Maybe like > this: > > ```js > function* take(n, iterable) { > let iterator = iterable[Symbol.iterator](); > n = +n; // make sure it's a number, so that n>0 does never throw > let forwardReturn = true; > try { > while (n > 0) { > let item = iterator.next(); > if (item.done) { > forwardReturn = false; > return item.value; > } > yield item.value; > n--; > } > forwardReturn = false; > } catch (e) { > forwardReturn = false; > iterator.throw(e); > } finally { > if (forwardReturn) { > iterator.return(); > } > } > } > ``` > The above code also has the additional nice property that it call `.return()` > on the iterator when `n` values have been taken out of it. > > That’s not what all the other constructs in ES6 do: they only call `return()` > if iteration stops abruptly. > > Also missing from this code: checking whether the iterator actually has the > methods `return()` and `throw()` and responding accordingly. -- Dr. Axel Rauschmayer [email protected] rauschma.de
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

