Browse Source

fix(subapp-loading): unmountMicroApps 卸载竞态修复

- 原 filter(async…) 使 await 不被等待,卸载为发射后不管,旧实例与新实例
  并发争抢容器;multipleApp.some 为函数引用恒真的笔误一并修正
- 改为顺序 await 卸载 + 单个失败不阻断 + 卸载后清理注册表
86132 4 days ago
parent
commit
f4b3e2d61e
1 changed files with 13 additions and 7 deletions
  1. 13 7
      src/qiankun/index.ts

+ 13 - 7
src/qiankun/index.ts

@@ -37,13 +37,19 @@ const mountMicroApp = (name, isReFresh = false) => {
 
 // 卸载app的方法
 const unmountMicroApps = async (multipleApp) => {
-  if (JSON.stringify(activeApps) !== '{}' && multipleApp.some) {
-    for (const key in activeApps) {
-      multipleApp.filter(async (name) => {
-        if (name.includes(key)) {
-          await activeApps[key].unmount();
-        }
-      });
+  // [fix-subapp-loading] 修复卸载竞态:原实现用 multipleApp.filter(async (name) => { await …unmount() })
+  // —— async 回调使 filter 立即返回、await 不被任何方等待,卸载是"发射后不管";
+  // 且判断条件 multipleApp.some 是函数引用(恒真)。改为顺序 await 逐个卸载,完成后清理注册表,
+  // 避免旧实例与新实例并存争抢容器/共享状态(子应用切页互清场景)。
+  if (!multipleApp || multipleApp.length === 0) return;
+  for (const key of Object.keys(activeApps)) {
+    if (multipleApp.some((name) => name.includes(key))) {
+      try {
+        await activeApps[key].unmount();
+      } catch (e) {
+        console.error('[fix-subapp-loading] 微应用卸载失败:', key, e);
+      }
+      delete activeApps[key];
     }
   }
 };