如何在 JavaScript 中顺序组合两个同步迭代器?
How to sequentially combine two sync iterators in JavaScript?
假设我们有两个异步迭代器,
const asyncIterable1 = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
const asyncIterable2 = {
[Symbol.asyncIterator]() {
return {
i: 3,
next() {
if (this.i < 5) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
现在,有没有一种方法可以将这两个迭代器组合成一个迭代器,从而 return 0,1,2 然后是 3,4 的序列?
是的,我会使用 yield*
:
const combine = (a, b) => (function* () { yield* a; yield* b; })();
const iterator = combine(
(function* () { yield 1; yield 2; })(),
(function* () { yield 3; yield 4; })()
);
console.log(iterator.next(), iterator.next(), iterator.next(), iterator.next(), iterator.next());
这类似于异步迭代器。不过,您将失去第一个迭代器的 return 值(“完成收益”)。但是您可以捕获它(值 yield*
的计算结果为)。
当然,如果您属于喜欢重新发明轮子的人,您也可以在没有生成器函数的情况下“手动”实现此类功能:
function combine(...iterators) {
let pos = 0, iterator = iterators[pos];
return {
next() {
let result = { done: true };
do {
result = iterator.next();
if(!result.done) break;
iterator = iterators[ pos++ ];
} while(iterator)
return result;
}
};
}
const iterator = combine(
(function* () { yield 1; yield 2; })(),
(function* () { yield 3; yield 4; })()
);
console.log(iterator.next(), iterator.next(), iterator.next(), iterator.next(), iterator.next());
除了 Jonas 的出色回答之外,我们还可以进一步概括并组合任意数量的迭代器:
let combine = function*(...iterators) {
for (let it of iterators) yield* it;
};
假设我们有两个异步迭代器,
const asyncIterable1 = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
const asyncIterable2 = {
[Symbol.asyncIterator]() {
return {
i: 3,
next() {
if (this.i < 5) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
现在,有没有一种方法可以将这两个迭代器组合成一个迭代器,从而 return 0,1,2 然后是 3,4 的序列?
是的,我会使用 yield*
:
const combine = (a, b) => (function* () { yield* a; yield* b; })();
const iterator = combine(
(function* () { yield 1; yield 2; })(),
(function* () { yield 3; yield 4; })()
);
console.log(iterator.next(), iterator.next(), iterator.next(), iterator.next(), iterator.next());
这类似于异步迭代器。不过,您将失去第一个迭代器的 return 值(“完成收益”)。但是您可以捕获它(值 yield*
的计算结果为)。
当然,如果您属于喜欢重新发明轮子的人,您也可以在没有生成器函数的情况下“手动”实现此类功能:
function combine(...iterators) {
let pos = 0, iterator = iterators[pos];
return {
next() {
let result = { done: true };
do {
result = iterator.next();
if(!result.done) break;
iterator = iterators[ pos++ ];
} while(iterator)
return result;
}
};
}
const iterator = combine(
(function* () { yield 1; yield 2; })(),
(function* () { yield 3; yield 4; })()
);
console.log(iterator.next(), iterator.next(), iterator.next(), iterator.next(), iterator.next());
除了 Jonas 的出色回答之外,我们还可以进一步概括并组合任意数量的迭代器:
let combine = function*(...iterators) {
for (let it of iterators) yield* it;
};