如何正确设置Interval Generator?

问题描述 投票:2回答:5

目标:我想创建一个在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
5个回答
5
投票

你记得变量中的对象而不是第二次调用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)

1
投票

您也可以使用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)
    })
  }
})();

0
投票

只是,存储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)

0
投票
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.

0
投票

另一种方法是使用相对较新的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);
    }
})();
© www.soinside.com 2019 - 2024. All rights reserved.