sdg*_*sdh 11 javascript generator async-await babeljs ecmascript-next
假设我有一个函数接受生成器并返回第一个n元素的另一个生成器:
const take = function * (n, xs) {
console.assert(n >= 0);
let i = 0;
for (const x of xs) {
if (i == n) {
break;
}
yield x;
i++;
}
};
Run Code Online (Sandbox Code Playgroud)
用法如下:
const evens = function * () {
let i = 0;
while (true) {
yield i;
i += 2;
}
};
for (const x of take(10, evens())) {
console.log(x);
}
Run Code Online (Sandbox Code Playgroud)
现在想象一下,evens也是async(见这个答案的设置):
const evensAsync = async function * () {
let i = 0;
while (true) {
yield i;
i += 2;
}
};
Run Code Online (Sandbox Code Playgroud)
当然,这不适用于take:
const main = async () => {
for await (const x of take(10, evensAsync())) {
console.log(x);
}
};
main().catch(e => console.error(e));
Run Code Online (Sandbox Code Playgroud)
现在,我可以定义一个take变体async:
const takeAsync = async function * (n, xs) {
console.assert(n >= 0);
let i = 0;
for await (const x of xs) {
if (i == n) {
break;
}
yield x;
i++;
}
};
const main = async () => {
for await (const x of takeAsync(10, evensAsync())) {
console.log(x);
}
};
main().catch(e => console.error(e));
Run Code Online (Sandbox Code Playgroud)
...... 但是麻烦啊!
有没有办法在JavaScript中自动"异步"生成器函数?
\n\n\n有没有办法在 JavaScript 中自动“异步”生成器函数?
\n
不。异步和同步发电机实在是太不同了。您将需要两种不同的实现take,没有办法解决它。
不过,您可以动态选择要选择哪一个:
\n\nasync function* takeAsync(asyncIterable) { \xe2\x80\xa6 }\nfunction* takeSync(iterable) { \xe2\x80\xa6 }\n\nfunction take(obj) {\n if (typeof obj[Symbol.asyncIterator] == "function") return takeAsync(obj);\n if (typeof obj[Symbol.iterator] == "function") return takeSync(obj);\n throw new TypeError("not an iterable object");\n}\nRun Code Online (Sandbox Code Playgroud)\n\n一般来说不可能编写一个asyncify可以像asyncify(takeSync)(10, evensAsync()). 人们也许能够将一些适用于takeSync和 的东西组合在一起mapSync,依赖于它们为每个输入项精确输出一项的事实,但它会非常脆弱,并且不适用于其他迭代函数,例如filter。
也就是说,当然可以概括并提供抽象。
\n\nfunction taker(n) {\n return {\n done: n > 0,\n *step(element) { /* if (n > 0) */ yield element; return taker(n-1); },\n result: null\n }\n}\nfunction mapper(fn) {\n return {\n done: false,\n *step(element) { yield fn(element); return this; }\n result: null\n }\n}\n\nfunction makeIterator(t) {\n return function*(iterable) {\n for (let element of iterable) {\n t = yield* t.step(element);\n if (t.done) break;\n }\n return t.result;\n };\n}\nfunction makeAsyncIterator(t) {\n return async function*(asyncIterable) {\n for await (let element of asyncIterable) {\n t = yield* t.step(element);\n if (t.done) break;\n }\n return t.result;\n };\n}\nRun Code Online (Sandbox Code Playgroud)\n\n(它无耻地剥夺了换能器的概念- 也没有进行任何测试)
\n| 归档时间: |
|
| 查看次数: |
100 次 |
| 最近记录: |