ES6 Generator

时间:2016-09-02 15:38:30

标签: javascript iterator ecmascript-6 generator

如何为生成器实现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); 
}

4 个答案:

答案 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().donefalsehasNext对象的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)
}
//...

您可以尝试一下 https://repl.it/repls/YummyWrathfulRhombus

答案 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);
}