Я хочу перезапустить итерацию после того, как итератор достигнет состояния готовности. Просто посмотрите на пример:
const newMap = new Map<string, string>([
['key1', 'value1'],
['key2', 'value2']
]);
const iterator = newMap.values() // It can be newMap.entries()
iterator.next().value // prints value1
iterator.next().value //prints value2
iterator.next().value //prints undefined
Я просто хочу что-то вроде:
iterator.restart();
iterator.next().value // prints value1
Я думал о том, чтобы просто поделиться одним свойством с другими службами и просто контролировать поток с его помощью, но, похоже, нет возможности перезапустить и повторно использовать это. может быть есть лучшие решения проблемы. Спасибо большое.
Вызовите .values
(или любой другой способ) еще раз.
const newMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
let iterator = newMap.values() // It can be newMap.entries()
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) //prints value2
console.info(iterator.next().value) //prints undefined
iterator = newMap.values()
console.info(iterator.next().value) // prints value1
Итераторы нельзя использовать повторно — вам придется создавать их заново каждый раз, когда вы хотите начать с самого начала.
Если вам нужны бесконечно повторяющиеся значения, вы можете создать функцию генератора, которая кэширует значения в первый раз, а затем постоянно выдает вам кэшированные значения с самого начала:
function* repeat(iterable) {
const cache = [];
//lazily supply the values from the iterable while caching them
for (const next of iterable) {
cache.push(next);
yield next;
}
//delegate to the cache at this point
while(true)
yield* cache;
}
const newMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
const iterator = repeat(newMap.values()) // It can be newMap.entries()
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
В качестве альтернативы, если вы не хотите кэшировать, вы можете упростить реализацию repeat()
, взяв функцию, которая дает вам итерацию. Каждый раз, когда вы вызываете его, вы получаете новый и делегируете его навсегда:
function* repeat(iterableSupplier) {
//delegate to the value from the supplier
while(true)
yield* iterableSupplier();
}
const newMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
const iterator = repeat(() => newMap.values()) // It can be newMap.entries()
// give a function ^^^^^
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
console.info(iterator.next().value) // prints value1
console.info(iterator.next().value) // prints value2
Подробнее о:
function*
- функции генератораyield*
— делегирование другому итерируемому объектуВы можете создать свой собственный итератор, который при запросе снова вызывает newMap.values():
const newMap = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
const myIterator = (() => {
let currentIterator = newMap.values();
return {
next() {
return currentIterator.next();
},
restart() {
currentIterator = newMap.values();
}
}
})()
console.info(myIterator.next().value) // prints value1
console.info(myIterator.next().value) //prints value2
console.info(myIterator.next().value) //prints undefined
myIterator.restart();
console.info(myIterator.next().value) // prints value1
Вы можете вызвать
newMap.values()
снова. Этого достаточно?