Skip to content

Commit 5ca119a

Browse files
Allow iterables in PersistencePromise.map/forEach/waitFor (#1269)
1 parent c577a7e commit 5ca119a

File tree

4 files changed

+59
-24
lines changed

4 files changed

+59
-24
lines changed

packages/firestore/src/core/sync_engine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
684684
queryView.targetId
685685
);
686686
this.limboDocumentRefs.removeReferencesForId(queryView.targetId);
687-
await PersistencePromise.forEach(limboKeys.toArray(), limboKey => {
687+
await PersistencePromise.forEach(limboKeys, limboKey => {
688688
return this.limboDocumentRefs
689689
.containsKey(null, limboKey)
690690
.next(isReferenced => {

packages/firestore/src/local/persistence_promise.ts

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -170,49 +170,54 @@ export class PersistencePromise<T> {
170170

171171
static waitFor(
172172
// tslint:disable-next-line:no-any Accept all Promise types in waitFor().
173-
all: Array<PersistencePromise<any>>
173+
all: Iterable<PersistencePromise<any>>
174174
): PersistencePromise<void> {
175-
const expectedCount = all.length;
176-
if (expectedCount === 0) {
177-
return PersistencePromise.resolve();
178-
}
179-
180-
let resolvedCount = 0;
175+
const it = all[Symbol.iterator]();
181176
return new PersistencePromise<void>((resolve, reject) => {
182-
for (const promise of all) {
183-
promise.next(
177+
let expectedCount = 0;
178+
let resolvedCount = 0;
179+
180+
let result = it.next();
181+
while (!result.done) {
182+
++expectedCount;
183+
result.value.next(
184184
() => {
185185
++resolvedCount;
186-
if (resolvedCount === expectedCount) {
186+
if (result.done && resolvedCount === expectedCount) {
187187
resolve();
188188
}
189189
},
190190
err => reject(err)
191191
);
192+
result = it.next();
193+
}
194+
195+
if (resolvedCount === expectedCount) {
196+
resolve();
192197
}
193198
});
194199
}
195200

196-
static map<R>(all: Array<PersistencePromise<R>>): PersistencePromise<R[]> {
201+
static map<R>(all: Iterable<PersistencePromise<R>>): PersistencePromise<R[]> {
197202
const results: R[] = [];
198-
const promises: Array<PersistencePromise<void>> = [];
199-
for (let i = 0; i < all.length; ++i) {
200-
promises[i] = all[i].next(result => {
201-
results[i] = result;
202-
});
203-
}
204-
return PersistencePromise.waitFor(promises).next(() => {
205-
return results;
206-
});
203+
return PersistencePromise.forEach(all, result => {
204+
results.push(result);
205+
return PersistencePromise.resolve();
206+
}).next(() => results);
207207
}
208208

209209
static forEach<T>(
210-
elements: T[],
210+
all: Iterable<T>,
211211
callback: (T) => PersistencePromise<void>
212212
): PersistencePromise<void> {
213+
const it = all[Symbol.iterator]();
214+
213215
let p = PersistencePromise.resolve();
214-
for (const element of elements) {
215-
p = p.next(() => callback(element));
216+
let result = it.next();
217+
while (!result.done) {
218+
const value = result.value;
219+
p = p.next(() => callback(value));
220+
result = it.next();
216221
}
217222
return p;
218223
}

packages/firestore/src/util/sorted_map.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,21 @@ export class SortedMap<K, V> {
168168
getReverseIteratorFrom(key: K): SortedMapIterator<K, V> {
169169
return new SortedMapIterator<K, V>(this.root, key, this.comparator, true);
170170
}
171+
172+
[Symbol.iterator](): Iterator<Entry<K, V>> {
173+
const it = this.getIterator();
174+
return {
175+
next(): IteratorResult<Entry<K, V>> {
176+
if (it.hasNext()) {
177+
return { done: false, value: it.getNext() };
178+
} else {
179+
// The TypeScript typings don't allow `undefined` for Iterator<T>,
180+
// so we return an empty object instead.
181+
return { done: true, value: {} as Entry<K, V> };
182+
}
183+
}
184+
};
185+
}
171186
} // end SortedMap
172187

173188
// An iterator over an LLRBNode.

packages/firestore/src/util/sorted_set.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ export class SortedSet<T> {
154154
return 'SortedSet(' + result.toString() + ')';
155155
}
156156

157+
[Symbol.iterator](): Iterator<T> {
158+
const it = this.data.getIterator();
159+
return {
160+
next(): IteratorResult<T> {
161+
if (it.hasNext()) {
162+
return { done: false, value: it.getNext().key };
163+
} else {
164+
// The TypeScript typings don't allow `undefined` for Iterator<T>,
165+
// so we return an empty object instead.
166+
return { done: true, value: {} as T };
167+
}
168+
}
169+
};
170+
}
171+
157172
private copy(data: SortedMap<T, boolean>): SortedSet<T> {
158173
const result = new SortedSet(this.comparator);
159174
result.data = data;

0 commit comments

Comments
 (0)