【问题标题】:How to iterate over the results of a generator function如何迭代生成器函数的结果
【发布时间】:2014-11-12 01:38:20
【问题描述】:

有没有更好的方法来迭代生成器的结果,我的 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)) ;
    }
}

【问题讨论】:

    标签: javascript node.js generator ecmascript-6


    【解决方案1】:

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

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

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

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

    【讨论】:

    • “for of”正是我想要的(双关语)——谢谢。我会将“while 循环”选项与我提到的“for 循环”选项混为一谈,就像我提到的非常 C++/Java/C# 一样 - 肯定它可以工作,但那条线上有很多事情发生,而且它不是超级可读...
    • 嗯,while 非常地道。但是for..of 在可读性方面胜过它——并且是生成器的完美搭档。 )
    • 用索引迭代怎么样?
    • @Weilory:保留你自己的柜台。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 2020-03-10
      • 1970-01-01
      • 2018-05-16
      • 2012-06-27
      • 2021-09-30
      相关资源
      最近更新 更多