我有一个异步生成器:
async function* foo() {
yield "wait...";
await new Promise(r=>setTimeout(r, 900));
yield new Promise(r=>setTimeout(()=>r("okay!"), 100));
}
async function main() {
for await (let item of foo()) {
let result = await item;
console.log(result);
}
}
main();
但是使用打字稿2.3这给了我错误:
错误TS2318:找不到全局类型' AsyncIterableIterator'。 example.ts(10,26):
错误TS2504:类型必须有' Symbol.asyncIterator'返回异步迭代器的方法。
如何修复此错误以及如何运行异步生成器?
答案 0 :(得分:25)
Symbol.asyncIterator
是esnext
功能;因此,您必须明确定位esnext
,或添加esnext.asynciterable
库,以获取支持语法的typescript。但是,typescript目前在运行时不处理符号的实现,所以你需要进行polyfill。
在"esnext.asynciterable"
lib
添加到tsconfig.json
{
"compilerOptions": {
"target": "es2015",
"moduleResolution": "node",
"module": "commonjs",
"lib": [
"dom",
"es2015",
"esnext.asynciterable"
]
}
}
您可以在执行任何其他操作之前简单地创建新符号来填充Symbol.asyncIterator
。
if(Symbol["asyncIterator"] === undefined) ((Symbol as any)["asyncIterator"]) = Symbol.for("asyncIterator");
正常编译并运行。
这也适用于任何可重复使用的软件包 - 最好是在模块的第一行main
脚本
如果您的目标是节点7及更高版本,您实际上可以使用标志本机运行异步迭代器。
在tsconfig.json中设置target: "esnext"
,编译并使用
node --harmony_async_iteration example.js
同样可用于ts节点,您可以在其中直接运行它。
ts-node --harmony_async_iteration example.ts
使用Node 9;它已在--harmony
标志
从节点10开始;它默认启用。
当你将打包的async-gen代码与babel的webpack包中的down-compile混合时,我遇到了一些兼容性问题。 可能应该是babel的polyfill如何查找符号,然后如果缺少则创建一个符号。兼容性问题是,看起来babel代码并不认为typescript(+ Symbol polyfill)代码具有Symbol.asyncIterable
密钥条目。
也可以使用babel插件将使用的相同符号polyfill来避免此问题:
import "core-js/modules/es7.symbol.async-iterator"