什么 AsyncGenerator TypeScript 类型会产生 Promise?

Dan*_*scu 3 iterable generator typescript

我正在尝试为下面的函数分配一个返回类型:

async function *sleepyNumbers() {  // what TypeScript type is this?
  let n = 0;
  while (true) {
    yield new Promise(resolve => resolve(n++));
    await new Promise(resolve => setTimeout(resolve, 500));
  }
}

(async () => {
  for await (const i of sleepyNumbers())
    console.log(i);
})();
Run Code Online (Sandbox Code Playgroud)

生成器正在生成一个解析为number. 将类型设置为Promise<number>失败并显示以下错误消息:

TS2739:“AsyncGenerator”类型缺少“Promise”类型中的以下属性:然后,捕获,[Symbol.toStringTag],最后

Iterable 导致了类似的错误。

我可以将类型设置为,AsyncGenerator但这还不够具体。此函数的返回类型的正确 TypeScript 语法是什么?

eri*_*icP 13

因为很多人看到这里都需要一些退出条件,所以我调整了这个问题和Aleksey L. 的答案

  1. 使其在 4 次迭代后停止:
  2. 修复结果error TS2534: A function returning 'never' cannot have a reachable end point.(使用 lib“es2018.asyncgenerator”进行测试)。
async function* sleepyNumbers(count: number): AsyncGenerator<number, void, void> {
  let n = 0;
  while (n < count) {
    yield new Promise<number>(resolve => resolve(n++));
    await new Promise(resolve => setTimeout(resolve, 250));
  }
}

(async () => {
  for await (const i of sleepyNumbers(4))
    console.log(i);
})();
Run Code Online (Sandbox Code Playgroud)

#2 需要使第二个模板 arg 成为AsyncGeneratorvoid因为生成器函数(function*)在没有返回的情况下从末尾脱落并且调用者返回:

{ value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)

调整生成器以在完成后传递最终值,我们看到第二个模板参数的使用:

{ value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)

,产生输出:

{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
Finished with: { value: 'some string', done: true }
past end 1: { value: undefined, done: true }
past end 2: { value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)

显然,在生成器完成后敲击迭代器总是会返回value: undefined.

太棒了;(就好像这还没有出现在 tldr-land 中一样),我们一直在使用TReturnAsyncGenerator 模板的参数:

async function* sleepyNumbers(count: number): AsyncGenerator<number, string, void> {
  let n = 0;
  while (n < count) {
    yield new Promise<number>(resolve => resolve(n++));
    await new Promise(resolve => setTimeout(resolve, 250));
  }
  return 'some string';
}

(async () => {
  const it = sleepyNumbers(4);
  let res;
  for (res = await it.next(); !res.done; res = await it.next())
    console.log(res);
  console.log('Finished with:', res);
  console.log('past end 1:', await it.next());
  console.log('past end 2:', await it.next());
})();
Run Code Online (Sandbox Code Playgroud)

(per node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts),映射到TReturnin

{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
Finished with: { value: 'some string', done: true }
past end 1: { value: undefined, done: true }
past end 2: { value: undefined, done: true }
Run Code Online (Sandbox Code Playgroud)

(根据 lib.es2015.iterable.d.ts)


Ale*_* L. 6

它将是AsyncGenerator<number, never, void>

number-next结果
never返回
void-next没有得到任何参数

您还需要明确键入一个承诺解析:

yield new Promise<number>(resolve => resolve(n++));

全部一起:

async function *sleepyNumbers(): AsyncGenerator<number, never, void> {
    let n = 0;
    while (true) {
        yield new Promise<number>(resolve => resolve(n++));
        await new Promise(resolve => setTimeout(resolve, 500));
    }
}

(async () => {
    for await (const i of sleepyNumbers())
        console.log(i);
})();
Run Code Online (Sandbox Code Playgroud)