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

How to iterate over the results of a generator function

本文关键字:函数 结果 何迭代 迭代      更新时间:2023-09-26

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

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

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

对于这个迭代问题,有没有一个更优雅的解决方案。我的意思是,这看起来像Java/C#中的传统迭代器,还不错。像"each"这样的东西会超级可读。。。不管怎样,这是我的希望。

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

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

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

如果没有,你已经见过几次了:

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

for ... of是一个优雅的解决方案,但没有得到全面支持,然而while (!(next = cursor.next()).done) {是一个非常神秘的解决方案。人们可能会问自己,为什么(var x = someFunctionCall())被评估为true另一个将回答CCD_ 6。

出于这个原因,为了给答案另一种形状,也可以使用递归函数来完成。

function loopThose(items) {
    const item = items.next();
    // doStuff(item);
    if (!item.done) {
        loopThose(items);
    }
}

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

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

生成器函数产生可能失败的承诺的地方:

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