如何为生成器实现hasNext()方法。我已经尝试了很多选项,比如将生成器添加为return语句并从闭包中产生。获得第一个值打印它然后使用while等,但它们都没有实际工作。
我知道我可以像How to loop the JavaScript iterator that comes from generator?一样使用,但仍然想知道我是否可以添加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);
}
答案 0 :(得分:5)
循环迭代器的简单非if (!is_user_logged_in()) {
auth_redirect(); // THIS PART WORKS ALREADY
} else {
$basedir = '/path/to/wp-content/uploads/gravity-forms/';
$file = realpath($basedir . $_SERVER['REQUEST_URI']);
if ($file === false || strpos($file, $basedir) !== 0 || !file_exists($file)) {
// error
} else {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
}
方法是
for…of
如果你真的想使用for (let iterator = range(1, 10), r; !(r = iterator.next()).done; ) {
console.log(r.value);
}
,你也可以这样做,但这有点奇怪:
hasNext
答案 1 :(得分:0)
通过检查range
是否可以创建并返回hasNext
Boolean
定义为start + 1 < end
的对象;递归调用函数hasNext
如果生成器.next().done
为false
且hasNext
对象的generator.next().value
属性设置为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);
答案 2 :(得分:0)
我创建了这个简单的模块。它允许您装饰任何迭代器并获取是否有更多元素的信息。
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)
}
//...
答案 3 :(得分:0)
这是另一种选择。不使用生成器函数,而是创建一个常规函数并让它返回一个带有 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);
}