什么 AsyncGenerator TypeScript 类型会产生 Promise?
Posted
技术标签:
【中文标题】什么 AsyncGenerator TypeScript 类型会产生 Promise?【英文标题】:What AsyncGenerator TypeScript type yields a Promise? 【发布时间】:2020-06-26 03:22:00 【问题描述】:我正在尝试为以下函数分配返回类型:
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);
)();
生成器正在生成一个解析为 number
的 Promise。将类型设置为 Promise<number>
失败并显示以下错误消息:
TS2739:“AsyncGenerator”类型缺少“Promise”类型的以下属性:then、catch、[Symbol.toStringTag]、finally
Iterable
导致了类似的错误。
我可以将类型设置为AsyncGenerator
,但这还不够具体。该函数的返回类型的正确 TypeScript 语法是什么?
【问题讨论】:
【参考方案1】:它将是AsyncGenerator<number, never, void>
:
number
- next
结果never
返回void
- next
没有得到任何参数
您还需要显式键入一个 promise resolve:
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);
)();
【讨论】:
让 n = 0;产量 n++; while (true) yield new Promise(resolve => setTimeout(resolve, 500, n++));【参考方案2】:因为很多人看这里都需要一些退出条件,所以我将问题和Aleksey L.'s answer 调整为:
-
在 4 次迭代后停止:
修复生成的
error TS2534: A function returning 'never' cannot have a reachable end point.
(使用库“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);
)();
#2 需要将第二个模板 arg 设置为 AsyncGenerator
为 void
,因为生成器函数(function*
)在没有返回的情况下落到最后,调用者返回:
value: undefined, done: true
调整生成器以在完成后传递一个最终值,我们看到了第二个模板参数的使用:
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());
)();
,产生输出:
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
显然,在生成器完成后敲击迭代器总是会返回 value: undefined
。
tldr;(好像这在 tldr-land 中还没有),我们一直在使用 AsyncGenerator 模板的 TReturn
参数:
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> extends AsyncIterator<T, TReturn, TNext>
// NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.
next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;
return(value: TReturn | PromiseLike<TReturn>): Promise<IteratorResult<T, TReturn>>;
throw(e: any): Promise<IteratorResult<T, TReturn>>;
[Symbol.asyncIterator](): AsyncGenerator<T, TReturn, TNext>;
(根据node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts
),映射到TReturn
in
interface IteratorYieldResult<TYield>
done?: false;
value: TYield;
interface IteratorReturnResult<TReturn>
done: true;
value: TReturn;
type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
(根据 lib.es2015.iterable.d.ts)
【讨论】:
以上是关于什么 AsyncGenerator TypeScript 类型会产生 Promise?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复错误“找不到此相关模块:* ./src/main.js in multi (webpack)-dev-server”在 npm run serve in vue3.x with typescr