【问题标题】:How to setInterval Generator correctly?如何正确设置间隔生成器?
【发布时间】:2018-01-13 15:25:51
【问题描述】:

目标: 我想创建一个在setInterval()console.log 1 到10 中调用的生成器函数。

问题: 为了最后clearInterval(),我需要一个条件来检查gen.next().done === true。 但每次条件运行时,它实际上都会调用另一个.next() 所以我得到的最终打印是: 1 3 5 7 9 undefined

如何在不调用 .next() 的情况下设置 done == true 条件

function* myGen(){
    let counter = 0;
    for(let i = 0 ; i <= 10; i++){
        yield counter++;    
    }
}

const gen = myGen();
const start = setInterval(() => {
    if(gen.next().done){
        clearInterval(start);
    } else {
        console.log(gen.next().value);  
    }
}, 1500)

【问题讨论】:

    标签: javascript generator setinterval


    【解决方案1】:

    您记住变量中的对象而不是第二次调用next

    function* myGen(){
        let counter = 0;
        for(let i = 0 ; i <= 10; i++){
            yield counter++;    
        }
    }
    
    const gen = myGen();
    const start = setInterval(() => {
        var next = gen.next();             // *** Save it here
        if(next.done){                     // *** Use it here...
            clearInterval(start);
        } else {
            console.log(next.value);       // *** ...and here
        }
    }, 150)

    【讨论】:

      【解决方案2】:

      您也可以使用for..of 循环、setTimeout()async/await 来避免检查.done 属性值的需要

      function* myGen() {
        let counter = 0;
        for (let i = 0; i <= 10; i++) {
          yield counter++;
        }
      }
      
      const gen = myGen();
      
      (async() => {
        for (let n of gen) {
          await new Promise(resolve => {
            setTimeout(() => {
              console.log(n);
              resolve()
            }, 1500)
          })
        }
      })();

      【讨论】:

        【解决方案3】:

        另一种方法是使用相对较新的 AsyncGenerator 功能
        https://github.com/tc39/proposal-async-iteration

        我认为它很好地抽象了问题(创建一个在每次迭代之间休眠的迭代器)。

        async function* sleepGenerator(numSleeps, sleepMillis) {
            for (let i = 0; i < numSleeps; i++) {
                await sleep(sleepMillis);
                yield {i, numSleeps, sleepMillis};
            }
        }
        
        function sleep(sleepMillis) {
            return new Promise(resolve => setTimeout(resolve, sleepMillis));
        }
        
        (async function run() {
            for await (const iterMeta of sleepGenerator(5, 500)) {
                console.log(iterMeta);
            }
        })();
        

        【讨论】:

          【解决方案4】:

          只是,存储nextValue

          function* myGen(){
              let counter = 0;
              for(let i = 0 ; i <= 10; i++){
                  yield counter++;    
              }
          }
          
          const gen = myGen();
          const start = setInterval(() => {
              let nextValue = gen.next();
              if(nextValue.done){
                  clearInterval(start);
              } else {
                  console.log(nextValue.value);  
              }
          }, 1500)
          

          【讨论】:

            【解决方案5】:
            function* myGen(){
            let counter = 0;
            for(let i = 0 ; i <= 10; i++){
                yield counter++;    
            }
            }
            
            const gen = myGen();
            const start = setInterval(() => {
            var genObj=gen.next();//keep next result as an object to avoid use next method twice
            
            if(genObj.done){
                clearInterval(start);
            } else {
                console.log(genObj.value);  
            }
            }, 1500)//I spent an hour learning this,late but get some konwledge,so,thanks.
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-12-03
              • 1970-01-01
              • 1970-01-01
              • 2019-10-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-12-21
              相关资源
              最近更新 更多