按顺序遍历不确定数量的 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()