Преглед на файлове

feat(adapter): batch subscribe and batch unsubscribe

Casper Dai преди 2 години
родител
ревизия
85adbb6a07
променени са 1 файла, в които са добавени 67 реда и са изтрити 18 реда
  1. 67 18
      src/utils/adapter/monitor.js

+ 67 - 18
src/utils/adapter/monitor.js

@@ -165,30 +165,43 @@ function checkMultiCard (id, multiCard) {
   }
 }
 
-function checkCb (id) {
-  const cbSet = cbMap.get(id)
-  const injectSet = injectMap.get(id)
-  if ((!cbSet || !cbSet.size) && (!injectSet || !injectSet.size)) {
-    client.unsubscribe([
-      `+/${id}/screen`,
-      `+/${id}/multifunctionCard/invoke/reply`
-    ])
-    cbMap.delete(id)
-    injectMap.delete(id)
-    deviceCache.delete(id)
-    console.log('monitor unsubscribe', id, '->', 'success')
+const subscribePromise = Promise.resolve()
+let subscribeIds = new Set()
+let subscribeWaiting = false
+let unsubscribeIds = new Set()
+let unsubscribeWaiting = false
+
+function doSubscribe () {
+  if (!subscribeWaiting) {
+    subscribeWaiting = true
+    subscribePromise.then(() => {
+      if (subscribeIds.size) {
+        const topics = []
+        subscribeIds.forEach(id => {
+          topics.push(
+            `+/${id}/screen`,
+            `+/${id}/multifunctionCard/invoke/reply`
+          )
+        })
+        client.subscribe(topics)
+        subscribeIds = new Set()
+        console.log('monitor subscribe', topics)
+      }
+      subscribeWaiting = false
+    })
   }
 }
 
 export function addListener (id, cb) {
   let cbSet = cbMap.get(id)
-  if (!cbSet) {
+  if (cbSet) {
+    if (unsubscribeIds.has(id)) {
+      unsubscribeIds.delete(id)
+    }
+  } else {
     cbMap.set(id, cbSet = new Set())
-    client.subscribe([
-      `+/${id}/screen`,
-      `+/${id}/multifunctionCard/invoke/reply`
-    ])
-    console.log('monitor subscribe', id, '->', 'success')
+    subscribeIds.add(id)
+    doSubscribe()
   }
   if (!cb) {
     return
@@ -204,12 +217,48 @@ export function addListener (id, cb) {
   cb(cache)
 }
 
+function doUnsubscribe () {
+  if (!unsubscribeWaiting) {
+    unsubscribeWaiting = true
+    subscribePromise.then(() => {
+      if (unsubscribeIds.size) {
+        const topics = []
+        unsubscribeIds.forEach(id => {
+          topics.push(
+            `+/${id}/screen`,
+            `+/${id}/multifunctionCard/invoke/reply`
+          )
+          cbMap.delete(id)
+          injectMap.delete(id)
+          deviceCache.delete(id)
+        })
+        client.unsubscribe(topics)
+        unsubscribeIds = new Set()
+        console.log('monitor unsubscribe', topics)
+      }
+      unsubscribeWaiting = false
+    })
+  }
+}
+
+function checkCb (id) {
+  const cbSet = cbMap.get(id)
+  const injectSet = injectMap.get(id)
+  if ((!cbSet || !cbSet.size) && (!injectSet || !injectSet.size)) {
+    unsubscribeIds.add(id)
+    doUnsubscribe()
+  }
+}
+
 export function removeListener (id, cb) {
   const cbSet = cbMap.get(id)
   if (!cbSet || !cbSet.has(cb)) {
     console.log('monitor', id, '->', 'not exsit')
     return
   }
+  if (subscribeIds.has(id)) {
+    subscribeIds.delete(id)
+  }
   console.log('monitor remove', id, '->', 'success')
   cbSet.delete(cb)
   checkCb(id)