Просмотр исходного кода

Make async for loops performant using Promise.all

nimbleghost 2 лет назад
Родитель
Сommit
9056d68fc9
2 измененных файлов с 37 добавлено и 39 удалено
  1. 10 9
      web/src/app/Poller.js
  2. 27 30
      web/src/app/SubscriptionManager.js

+ 10 - 9
web/src/app/Poller.js

@@ -21,15 +21,16 @@ class Poller {
   async pollAll() {
     console.log(`[Poller] Polling all subscriptions`);
     const subscriptions = await subscriptionManager.all();
-    for (const s of subscriptions) {
-      try {
-        // TODO(eslint): Switch to Promise.all
-        // eslint-disable-next-line no-await-in-loop
-        await this.poll(s);
-      } catch (e) {
-        console.log(`[Poller] Error polling ${s.id}`, e);
-      }
-    }
+
+    await Promise.all(
+      subscriptions.map(async (s) => {
+        try {
+          await this.poll(s);
+        } catch (e) {
+          console.log(`[Poller] Error polling ${s.id}`, e);
+        }
+      })
+    );
   }
 
   async poll(subscription) {

+ 27 - 30
web/src/app/SubscriptionManager.js

@@ -5,13 +5,12 @@ class SubscriptionManager {
   /** All subscriptions, including "new count"; this is a JOIN, see https://dexie.org/docs/API-Reference#joining */
   async all() {
     const subscriptions = await db.subscriptions.toArray();
-    await Promise.all(
-      subscriptions.map(async (s) => {
-        // eslint-disable-next-line no-param-reassign
-        s.new = await db.notifications.where({ subscriptionId: s.id, new: 1 }).count();
-      })
+    return Promise.all(
+      subscriptions.map(async (s) => ({
+        ...s,
+        new: await db.notifications.where({ subscriptionId: s.id, new: 1 }).count(),
+      }))
     );
-    return subscriptions;
   }
 
   async get(subscriptionId) {
@@ -40,33 +39,31 @@ class SubscriptionManager {
     console.log(`[SubscriptionManager] Syncing subscriptions from remote`, remoteSubscriptions);
 
     // Add remote subscriptions
-    const remoteIds = []; // = topicUrl(baseUrl, topic)
-    for (let i = 0; i < remoteSubscriptions.length; i += 1) {
-      const remote = remoteSubscriptions[i];
-      // TODO(eslint): Switch to Promise.all
-      // eslint-disable-next-line no-await-in-loop
-      const local = await this.add(remote.base_url, remote.topic, false);
-      const reservation = remoteReservations?.find((r) => remote.base_url === config.base_url && remote.topic === r.topic) || null;
-      // TODO(eslint): Switch to Promise.all
-      // eslint-disable-next-line no-await-in-loop
-      await this.update(local.id, {
-        displayName: remote.display_name, // May be undefined
-        reservation, // May be null!
-      });
-      remoteIds.push(local.id);
-    }
+    const remoteIds = await Promise.all(
+      remoteSubscriptions.map(async (remote) => {
+        const local = await this.add(remote.base_url, remote.topic, false);
+        const reservation = remoteReservations?.find((r) => remote.base_url === config.base_url && remote.topic === r.topic) || null;
+
+        await this.update(local.id, {
+          displayName: remote.display_name, // May be undefined
+          reservation, // May be null!
+        });
+
+        return local.id;
+      })
+    );
 
     // Remove local subscriptions that do not exist remotely
     const localSubscriptions = await db.subscriptions.toArray();
-    for (let i = 0; i < localSubscriptions.length; i += 1) {
-      const local = localSubscriptions[i];
-      const remoteExists = remoteIds.includes(local.id);
-      if (!local.internal && !remoteExists) {
-        // TODO(eslint): Switch to Promise.all
-        // eslint-disable-next-line no-await-in-loop
-        await this.remove(local.id);
-      }
-    }
+
+    await Promise.all(
+      localSubscriptions.map(async (local) => {
+        const remoteExists = remoteIds.includes(local.id);
+        if (!local.internal && !remoteExists) {
+          await this.remove(local.id);
+        }
+      })
+    );
   }
 
   async updateState(subscriptionId, state) {