Reputation: 5403
I have this class that has method next
returning a Promise
.
class PromiseGenerator {
constructor() {
this.limit = 100;
this.counter = 0;
}
next() {
this.counter++;
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(this.counter <= this.limit ? this.counter : false);
}, 500);
});
}
}
Though example shows 100
it could return unlimited number of promises.
I need to execute all the promises in sequential order.
How can I achieve it?
Only solution I came up so far is recursive:
const source = new PromiseGenerator();
(function loop() {
source.next().then(counter => {
if (counter) {
console.log(counter);
loop();
} else {
console.log('Done');
}
});
})();
As I understand Node
at the moment does not optimize tail calls and it may lead to stack growth.
Is there a better way of doing this?
if some Promise library has it it will work but it would be nice to understand how to achieve it without library as well.
Update 1: Sorry I didn't make it clear right away: I am not in control of PromiseGenerator
class, it is something I can use but cannot change. So the question is how to handle this situation.
Update 2: I went with @eikooc solution: Without generators
but just with async/await
. See example below.
Thanks!
Upvotes: 0
Views: 76
Reputation: 2563
Generators are a perfect match for this. Construct a generator with the function*
keyword:
function* promiseGenerator() {
while(!someCondition) {
yield new Promise((resolve, reject) => {})
}
}
And then call it with:
const source = promiseGenerator()
source.next()
This will continue to give you new values. The return looks like this {value: Promise, done: false}
until it is finished.
When the generator finishes the done
value will change to true
If you want to keep using the class and just want a loop. You can also combine your class with a async function:
async function loop() {
const source = new PromiseGenerator()
while (true) {
const result = await source.next()
if (result) {
console.log(result)
} else {
console.log('done')
break
}
}
}
loop()
Upvotes: 3