如何迭代生成器函数的结果

时间:2014-09-17 21:09:45

标签: javascript node.js generator ecmascript-6

有没有更好的方法来迭代生成器的结果,我的for循环很难看:

for(let job = readyJob.next(); !job.done; job = readyJob.next()){ } 

在上下文中,有一个生成器函数可以确定是否有一批工作,包括1 ... *作业(生成器也可以在批处理中不返回任何作业)。有一个连续循环实例化生成器并迭代批处理工作(日志记录)。

这个迭代问题是否有更优雅的解决方案。我的意思是这看起来像是来自Java / C#的传统迭代器,这也不错。像“每个”这样的东西都是超级可读的...无论如何,这是我的希望。

 let getReadyJob = function *(instance){
    let numJobs = 7 ; // getRandomInt(0, 10) ;
    for(let i = 0; i < numJobs; i++) {
        yield {
            jobId: '' + instance + '::' + i,
            jobReadyOn: (new Date()).valueOf()
        };
    }
}

然后

while(true){
    let readyJob = getReadyJob()

    for(let job = readyJob.next(); !job.done; job = readyJob.next()){
        console.log(JSON.stringify(job.value)) ;
    }
}

2 个答案:

答案 0 :(得分:4)

是的,如果您的环境已经支持for...of

for (var job of readyJob) {
  // ...
}

如果没有,已经看过几次:

var next;
while (!(next = readyJob.next()).done) {
   var job = next.value;
   // ...
}

答案 1 :(得分:0)

for ... of是一种优雅的解决方案,但并未获得整体支持,但是while (!(next = cursor.next()).done) {是一个非常隐秘的问题,人们可能会问自己,(var x = someFunctionCall())的评估结果如何true, 另一个人会回答welcome to javascript

基于这个原因并给出另一个答案,也可以使用递归函数来完成。

function loopThose(items) {
    const item = items.next();

    // doStuff(item);

    if (!item.done) {
        loopThose(items);
    }
}

真正的好处是当异步,尝试catch和自定义继续条件发挥作用时:

async function printKeys(items) {
    try {
       const item = await items.next();
       // doStuff(item);
       if (isConditionFulfil(item)) {
          await this.printKeys(items);
       }
    } catch (e){

    }
}

生成器函数产生的promise可能会失败:

function * list(){
  for (var i = 0; i<10; i++){
     yield fetch(buildResourceUrl(i)).then(res => res.json())
  }
}
相关问题