按顺序遍历不确定数量的 Promise
Go through undetermined number of Promises sequentially
我有这个 class 有方法 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);
});
}
}
尽管示例显示 100
它可以 return 无限数量的承诺。
我需要按顺序执行所有承诺。
如何实现?
到目前为止我想到的唯一解决方案是递归的:
const source = new PromiseGenerator();
(function loop() {
source.next().then(counter => {
if (counter) {
console.log(counter);
loop();
} else {
console.log('Done');
}
});
})();
据我了解Node
目前does not optimize tail calls,这可能会导致堆栈增长。
有更好的方法吗?
如果一些 Promise 库有它,它会工作,但如果能理解如何在没有库的情况下实现它会很好。
更新 1: 对不起,我没有马上说清楚:我无法控制 PromiseGenerator
class,这是我的事情可以使用但不能更改。所以问题是如何处理这种情况。
更新 2: 我使用了@eikooc 解决方案:没有 generators
但只有 async/await
。请参阅下面的示例。
谢谢!
Generators 非常适合这个。使用 function*
关键字构建生成器:
function* promiseGenerator() {
while(!someCondition) {
yield new Promise((resolve, reject) => {})
}
}
然后调用它:
const source = promiseGenerator()
source.next()
这将继续为您提供新的价值。 return 在完成之前看起来像这样 {value: Promise, done: false}
。
当生成器完成时,done
值将更改为 true
如果您想继续使用 class 并且只需要一个循环。您还可以将 class 与 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()
我有这个 class 有方法 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);
});
}
}
尽管示例显示 100
它可以 return 无限数量的承诺。
我需要按顺序执行所有承诺。
如何实现?
到目前为止我想到的唯一解决方案是递归的:
const source = new PromiseGenerator();
(function loop() {
source.next().then(counter => {
if (counter) {
console.log(counter);
loop();
} else {
console.log('Done');
}
});
})();
据我了解Node
目前does not optimize tail calls,这可能会导致堆栈增长。
有更好的方法吗?
如果一些 Promise 库有它,它会工作,但如果能理解如何在没有库的情况下实现它会很好。
更新 1: 对不起,我没有马上说清楚:我无法控制 PromiseGenerator
class,这是我的事情可以使用但不能更改。所以问题是如何处理这种情况。
更新 2: 我使用了@eikooc 解决方案:没有 generators
但只有 async/await
。请参阅下面的示例。
谢谢!
Generators 非常适合这个。使用 function*
关键字构建生成器:
function* promiseGenerator() {
while(!someCondition) {
yield new Promise((resolve, reject) => {})
}
}
然后调用它:
const source = promiseGenerator()
source.next()
这将继续为您提供新的价值。 return 在完成之前看起来像这样 {value: Promise, done: false}
。
当生成器完成时,done
值将更改为 true
如果您想继续使用 class 并且只需要一个循环。您还可以将 class 与 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()