用于 ES6 生成器的 hasNext()
hasNext() for ES6 Generator
我将如何为生成器实现 hasNext() 方法。我尝试了很多选项,例如将生成器添加为 return 语句并从闭包中产生。获取第一个值打印它,然后使用 while 等,但其中 none 实际上有效。
我知道我可以像 那样使用 for of 或 while,但仍然想知道我是否可以添加 hasNext()。
function *range(start,end){
while(start < end){
yield start;
start++
}
}
let iterator = range(1,10);
// so I can do something like this.
while(iterator.hasNext()){
console.log(iterator.next().value);
}
您可以通过检查 start + 1 < end
从 range
创建并 return 一个将 hasNext
定义为 Boolean
的对象;递归调用一个函数,hasNext
如果生成器 .next().done
是 false
并且 generator.next().value
处的对象的 hasNext
属性 设置为 true
, 否则执行其他任务
function* range(start, end) {
let next = () => start + 1 < end;
let g = {
hasNext: next(),
currentValue: start
};
while (start < end) {
yield g;
g.currentValue = ++start;
g.hasNext = next();
}
}
let iterator = range(1, 10);
function hasNext(gen) {
let curr = gen.next();
if (!curr.done) {
if (curr.value.hasNext) {
console.log(`hasNext:${curr.value.hasNext}`
, `currentValue:${curr.value.currentValue}`);
hasNext(gen);
} else {
console.log(JSON.stringify(curr.value, null, 2));
}
}
}
hasNext(iterator);
循环迭代器的简单非for…of
方法是
for (let iterator = range(1, 10), r; !(r = iterator.next()).done; ) {
console.log(r.value);
}
如果你真的想使用hasNext
,你也可以这样做,但是有点奇怪:
const iterator = range(1, 10);
iterator.hasNext = function hasNext() {
const r = this.next();
this.current = r.value;
return !r.done;
};
while (iterator.hasNext()) {
console.log(iterator.current);
}
我创建了这个简单的模块。它允许您装饰任何迭代器并获取是否有更多元素的信息。
https://www.npmjs.com/package/iterable-has-next
用法就这么简单:
//...
const { extendIterator } = require('iterable-has-next')
const extendedIterator = await extendIterator(yourIterator)
while (extendedIterator.hasNext()) {
const { value } = await extendedIterator.next()
console.log(value)
}
//...
这是另一种选择。不使用生成器函数,而是创建一个常规函数并让它 return 一个具有 hasNext()
和 next()
自定义实现的对象,并为 for...of
循环添加一个用户定义的可迭代对象:
function getRange(start, end) {
return {
hasNext() {
return start <= end;
},
next() {
return start <= end ? start++ : undefined;
},
*[Symbol.iterator]() {
while(start <= end) yield start++;
}
};
}
console.log('Test iteration A');
let iteratorA = getRange(1, 10);
while(iteratorA.hasNext()) {
console.log(iteratorA.next());
}
console.log('\n\nTest iteration B');
let iteratorB = getRange(20, 30);
for(let index of iteratorB) {
console.log(index);
}
我将如何为生成器实现 hasNext() 方法。我尝试了很多选项,例如将生成器添加为 return 语句并从闭包中产生。获取第一个值打印它,然后使用 while 等,但其中 none 实际上有效。
我知道我可以像
function *range(start,end){
while(start < end){
yield start;
start++
}
}
let iterator = range(1,10);
// so I can do something like this.
while(iterator.hasNext()){
console.log(iterator.next().value);
}
您可以通过检查 start + 1 < end
从 range
创建并 return 一个将 hasNext
定义为 Boolean
的对象;递归调用一个函数,hasNext
如果生成器 .next().done
是 false
并且 generator.next().value
处的对象的 hasNext
属性 设置为 true
, 否则执行其他任务
function* range(start, end) {
let next = () => start + 1 < end;
let g = {
hasNext: next(),
currentValue: start
};
while (start < end) {
yield g;
g.currentValue = ++start;
g.hasNext = next();
}
}
let iterator = range(1, 10);
function hasNext(gen) {
let curr = gen.next();
if (!curr.done) {
if (curr.value.hasNext) {
console.log(`hasNext:${curr.value.hasNext}`
, `currentValue:${curr.value.currentValue}`);
hasNext(gen);
} else {
console.log(JSON.stringify(curr.value, null, 2));
}
}
}
hasNext(iterator);
循环迭代器的简单非for…of
方法是
for (let iterator = range(1, 10), r; !(r = iterator.next()).done; ) {
console.log(r.value);
}
如果你真的想使用hasNext
,你也可以这样做,但是有点奇怪:
const iterator = range(1, 10);
iterator.hasNext = function hasNext() {
const r = this.next();
this.current = r.value;
return !r.done;
};
while (iterator.hasNext()) {
console.log(iterator.current);
}
我创建了这个简单的模块。它允许您装饰任何迭代器并获取是否有更多元素的信息。
https://www.npmjs.com/package/iterable-has-next
用法就这么简单:
//...
const { extendIterator } = require('iterable-has-next')
const extendedIterator = await extendIterator(yourIterator)
while (extendedIterator.hasNext()) {
const { value } = await extendedIterator.next()
console.log(value)
}
//...
这是另一种选择。不使用生成器函数,而是创建一个常规函数并让它 return 一个具有 hasNext()
和 next()
自定义实现的对象,并为 for...of
循环添加一个用户定义的可迭代对象:
function getRange(start, end) {
return {
hasNext() {
return start <= end;
},
next() {
return start <= end ? start++ : undefined;
},
*[Symbol.iterator]() {
while(start <= end) yield start++;
}
};
}
console.log('Test iteration A');
let iteratorA = getRange(1, 10);
while(iteratorA.hasNext()) {
console.log(iteratorA.next());
}
console.log('\n\nTest iteration B');
let iteratorB = getRange(20, 30);
for(let index of iteratorB) {
console.log(index);
}