Goal:
I want to create a generator function that is being invoked inside setInterval()
, and console.log
1 to 10.
the problem:
In order to clearInterval()
at the end I need a condition to check if gen.next().done === true
.
but every time the condition runs it actualy calls another .next()
so so final print i get is:
1 3 5 7 9 undefined
How do I set a done == true condition without calling .next()
?
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)
Goal:
I want to create a generator function that is being invoked inside setInterval()
, and console.log
1 to 10.
the problem:
In order to clearInterval()
at the end I need a condition to check if gen.next().done === true
.
but every time the condition runs it actualy calls another .next()
so so final print i get is:
1 3 5 7 9 undefined
How do I set a done == true condition without calling .next()
?
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)
Share
Improve this question
asked Jan 13, 2018 at 15:25
ueeieiieueeieiie
1,5622 gold badges18 silver badges43 bronze badges
5 Answers
Reset to default 11You remember the object in a variable rather than calling next
a second time:
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)
You can alternatively use for..of
loop, setTimeout()
, async/await
to avoid the need to check for .done
property value
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)
})
}
})();
Another way is to use the relatively new AsyncGenerator feature
https://github.com/tc39/proposal-async-iteration
I think it abstracts the problem nicely (creating an iterator that sleeps in between each 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);
}
})();
just, store the 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)
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.