微前端应用通信使用和原理

参考链接: [微前端][vue3 + vite + qiankun] 使用详解

一般来说,各个子应用是通过业务来划分的,不同业务线应该降低耦合度,尽量去避免通信,但是如果涉及到一些公共的状态或者操作,qiankun也是支持的。

qinkun提供了一个全局的GlobalState来共享数据,基座初始化之后,子应用可以监听到这个数据的变化,也能提交这个数据。

假设有如下一个具体的业务场景:有一个基座应用(主应用)和多个子应用(微前端应用)。我们假设有一个全局的用户信息状态(例如用户ID、用户名、权限等)需要在基座和所有子应用之间共享。当用户在基座应用中登录后,用户信息需要传递给所有子应用,同时子应用可能在某些操作后更新用户信息(例如更新用户昵称),并且其他子应用和基座需要响应这个更新。

步骤

  1. 基座应用初始化全局状态,包括用户信息。
  2. 基座应用在启动qiankun时,将全局状态传递给子应用。
  3. 子应用可以监听全局状态的变化,并在状态变化时更新自己的界面。
  4. 子应用也可以修改全局状态,并通知到基座和其他子应用。

具体实现

基座应用(主应用):

  1. 使用qiankun的initGlobalState方法初始化全局状态。
  2. 注册子应用,并将全局状态传递给子应用。
  3. 监听全局状态的变化,以便在基座中更新。

多个子应用需要共享用户登录状态、用户信息和权限数据,避免重复登录和权限校验。

javascript 复制代码
// 主应用 - 初始化全局状态
import { initGlobalState } from 'qiankun';

// 初始化状态
const initialState = {
  user: {
    id: null,
    name: '',
    avatar: '',
    roles: [],
    permissions: []
  },
  token: '',
  isLoggedIn: false
};

const actions = initGlobalState(initialState);

// 用户登录后更新状态
actions.setGlobalState({
  user: {
    id: 12345,
    name: '张三',
    avatar: '/avatars/zhangsan.jpg',
    roles: ['admin', 'user'],
    permissions: ['read', 'write', 'delete']
  },
  token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
  isLoggedIn: true
});

// 监听登录状态变化
actions.onGlobalStateChange((state, prevState) => {
  // 主应用自身的状态同步
  if (state.isLoggedIn !== prevState.isLoggedIn) {
    console.log('登录状态变化:', state.isLoggedIn);
    updateMainAppUI(state);
  }
});

子应用:

  1. 在生命周期函数中,获取基座传递的全局状态,并监听状态变化。
  2. 在适当的时候(例如用户操作后)使用setGlobalState更新全局状态。
jsx 复制代码
let globalAction = null;

// 子应用A - 用户管理
export async function mount(props) {
  // 保存全局状态操作对象
  globalAction = props;

  // 监听全局状态变化
  props.onGlobalStateChange((state, prevState) => {
    // 用户信息变化时更新界面
    if (state.user.id !== prevState.user.id) {
      updateUserProfile(state.user);
    }
    
    // 权限变化时重新检查
    if (state.user.permissions !== prevState.user.permissions) {
      checkPermissions(state.user.permissions);
    }
  }, true); // 立即执行一次
  
  // 渲染子应用
  renderApp(props);
}

  // 更新用户信息
  const updateUserInfo = (newUserInfo) => {
    globalAction.setGlobalState({
      user: {
        ...globalAction.getGlobalState().user,
        ...newUserInfo
      }
    });
  };
  
  // 检查权限
  const checkPermissions = (requiredPermission) => {
    const { permissions } = globalAction.getGlobalState().user;
    return permissions.includes(requiredPermission);
  };
  

原理

qiankun 的 initGlobalState 方法提供了一种在微前端架构中主应用与子应用之间通信的机制。其原理主要基于以下步骤:

状态初始化:主应用调用 initGlobalState 初始化全局状态,并返回一个对象,该对象包含设置状态、监听状态变化等方法。

状态存储:全局状态被存储在一个中心化的地方,并且可以被多个子应用访问。

状态更新:当主应用或子应用调用 setGlobalState 更新状态时,会触发所有已经注册的监听器(包括主应用和子应用)。

状态监听:子应用(或主应用)可以通过 onGlobalStateChange 注册监听函数,当全局状态发生变化时,会执行这些监听函数。

状态隔离:qiankun 会确保每个子应用都能独立地监听全局状态,并且不会互相干扰。

下面是一个简化的实现原理示例,帮助理解 qiankun 的全局状态管理:

javascript 复制代码
// 模拟 qiankun 的全局状态管理
let globalState = {}; // 全局状态
let listeners = [];   // 监听器列表

function initGlobalState(initialState = {}) {
  // 合并初始状态
  globalState = { ...globalState, ...initialState };

  // 返回一个对象,包含操作全局状态的方法
  return {
    // 设置全局状态
    setGlobalState(state) {
      const prevState = { ...globalState };
      globalState = { ...globalState, ...state };
      // 通知所有监听器
      listeners.forEach(listener => {
        listener(globalState, prevState);
      });
    },

    // 监听全局状态变化
    onGlobalStateChange(listener, immediate = false) {
      listeners.push(listener);
      // 如果立即执行,则立即调用一次监听器
      if (immediate) {
        listener(globalState, globalState);
      }
      // 返回一个取消监听的函数
      return () => {
        const index = listeners.indexOf(listener);
        if (index > -1) {
          listeners.splice(index, 1);
        }
      };
    },

    // 获取当前全局状态
    getGlobalState() {
      return globalState;
    },

    // 移除所有监听器(通常用于应用卸载时)
    offGlobalStateChange() {
      listeners = [];
    }
  };
}

// 主应用使用
const actions = initGlobalState({ user: 'main' });

// 子应用使用
// 假设子应用通过某种方式获取到 actions(通常是通过 props 传递)
// 子应用监听状态变化
const unsubscribe = actions.onGlobalStateChange((state, prevState) => {
  console.log('子应用监听到状态变化', state, prevState);
}, true);

// 子应用更新状态
actions.setGlobalState({ user: 'subapp' });

// 取消监听
// unsubscribe();

在实际的 qiankun 实现中,还会考虑以下方面:

状态隔离:确保子应用在卸载时自动取消监听,避免内存泄漏。

状态同步:当子应用初始化时,能够获取到最新的全局状态。

多实例支持:在多个子应用同时运行时,每个子应用都可以独立地监听和更新状态。

在 qiankun 的源码中,全局状态的管理是在 src/globalState.ts 中实现的。它使用了类似发布-订阅的模式,并且通过一个全局的变量来存储状态。主应用和子应用通过这个全局的变量进行通信。

注意:在子应用中,qiankun 会通过生命周期函数的参数将全局状态的操作方法传递给子应用,子应用在挂载时可以通过 props 获取到这些方法。

例如,在主应用中注册子应用时:

javascript 复制代码
import { registerMicroApps, start } from 'qiankun';

registerMicroApps([
  {
    name: 'subapp',
    entry: '//localhost:7100',
    container: '#subapp-container',
    activeRule: '/subapp',
    props: {
      // 传递全局状态操作方法
      onGlobalStateChange: actions.onGlobalStateChange,
      setGlobalState: actions.setGlobalState,
      getGlobalState: actions.getGlobalState,
    },
  },
]);

start();

在子应用中,在生命周期函数中接收:

javascript 复制代码
export async function mount(props) {
  // 子应用可以使用 props 上的方法
  props.onGlobalStateChange((state, prev) => {
    // 状态变化时的操作
  });
  
  props.setGlobalState({ ... });
}

这样,主应用和子应用就可以通过这个全局状态进行通信了。

Qiankun initGlobalState 全局状态通信原理与实现

状态管理架构

Qiankun 的全局状态管理基于发布-订阅模式,采用中心化的状态存储和事件通知机制

javascript 复制代码
// 简化的核心实现原理
class GlobalStateManager {
  constructor() {
    this.state = {};                    // 全局状态存储
    this.listeners = new Map();         // 监听器映射表
    this.subAppStates = new Map();      // 子应用状态快照
    this.isMainApp = true;              // 标识是否为主应用
  }

  // 初始化全局状态
  initGlobalState(initialState = {}) {
    this.state = { ...initialState };
    return this.createActions();
  }

  // 创建状态操作方法
  createActions() {
    return {
      setGlobalState: (state) => this.setGlobalState(state),
      onGlobalStateChange: (callback, immediately = false) => 
        this.onGlobalStateChange(callback, immediately),
      offGlobalStateChange: (callback) => this.offGlobalStateChange(callback),
      getGlobalState: () => this.getGlobalState()
    };
  }

  // 设置全局状态
  setGlobalState(state) {
    const prevState = { ...this.state };
    
    // 合并新状态
    this.state = {
      ...this.state,
      ...state
    };

    // 通知所有监听器
    this.notifyListeners(this.state, prevState);
    
    return true;
  }

  // 注册状态变化监听器
  onGlobalStateChange(callback, immediately = false) {
    const listenerId = Symbol('listener');
    
    this.listeners.set(listenerId, callback);
    
    // 立即执行一次
    if (immediately) {
      try {
        callback(this.state, this.state);
      } catch (error) {
        console.error('Global state listener error:', error);
      }
    }

    // 返回取消监听函数
    return () => {
      this.listeners.delete(listenerId);
    };
  }

  // 移除监听器
  offGlobalStateChange(callback) {
    for (const [id, listener] of this.listeners.entries()) {
      if (listener === callback) {
        this.listeners.delete(id);
        break;
      }
    }
  }

  // 获取当前状态
  getGlobalState() {
    return { ...this.state };
  }

  // 通知所有监听器
  notifyListeners(currentState, previousState) {
    this.listeners.forEach((listener, id) => {
      try {
        // 使用 setTimeout 确保异步执行,避免阻塞
        setTimeout(() => {
          if (this.listeners.has(id)) {
            listener(currentState, previousState);
          }
        }, 0);
      } catch (error) {
        console.error(`Listener ${id.toString()} error:`, error);
      }
    });
  }

  // 子应用挂载时的状态同步
  syncStateToSubApp(subAppName, actions) {
    // 保存子应用的状态操作引用
    this.subAppStates.set(subAppName, actions);
    
    // 返回子应用专用的状态操作对象
    return this.createSubAppActions(actions);
  }

  // 创建子应用专用的操作对象
  createSubAppActions(subAppActions) {
    return {
      ...subAppActions,
      // 可以在这里添加子应用特定的逻辑
      getSubAppState: () => this.getGlobalState()
    };
  }
}

完整实现源码解析

下面是更接近 Qiankun 实际实现的完整代码:

javascript 复制代码
// globalState.js - Qiankun 全局状态管理核心实现
class GlobalState {
  constructor() {
    // 全局状态存储
    this.state = {};
    
    // 监听器存储:Map<symbol, Function>
    this.listeners = new Map();
    
    // 标识是否已初始化
    this.initialized = false;
    
    // 主应用标识
    this.isMaster = typeof window !== 'undefined' && 
                   window.__POWERED_BY_QIANKUN__ !== true;
  }

  /**
   * 初始化全局状态
   * @param {Object} initialState 初始状态
   * @returns {Object} 状态操作对象
   */
  initGlobalState(initialState = {}) {
    if (this.initialized) {
      console.warn('[qiankun] Global state already initialized');
      return this.getActions();
    }

    this.state = this.deepClone(initialState);
    this.initialized = true;

    // 在开发模式下打印日志
    if (process.env.NODE_ENV === 'development') {
      console.log('[qiankun] Global state initialized:', this.state);
    }

    return this.getActions();
  }

  /**
   * 获取状态操作对象
   */
  getActions() {
    return {
      setGlobalState: this.setGlobalState.bind(this),
      onGlobalStateChange: this.onGlobalStateChange.bind(this),
      offGlobalStateChange: this.offGlobalStateChange.bind(this),
      getGlobalState: this.getGlobalState.bind(this),
    };
  }

  /**
   * 设置全局状态
   * @param {Object} state 新状态
   * @param {boolean} overwrite 是否覆盖整个状态
   */
  setGlobalState(state, overwrite = false) {
    if (!this.initialized) {
      console.error('[qiankun] Global state not initialized');
      return false;
    }

    const prevState = this.deepClone(this.state);
    
    if (overwrite) {
      this.state = this.deepClone(state);
    } else {
      this.state = this.mergeState(this.state, state);
    }

    // 触发监听器
    this.emit(prevState);

    if (process.env.NODE_ENV === 'development') {
      console.log('[qiankun] Global state updated:', {
        from: prevState,
        to: this.state
      });
    }

    return true;
  }

  /**
   * 注册状态变化监听器
   * @param {Function} listener 监听函数
   * @param {boolean} fireImmediately 是否立即执行
   */
  onGlobalStateChange(listener, fireImmediately = false) {
    if (typeof listener !== 'function') {
      throw new Error('[qiankun] Listener must be a function');
    }

    const listenerId = Symbol('qiankun-global-state-listener');
    this.listeners.set(listenerId, listener);

    // 立即执行一次
    if (fireImmediately) {
      try {
        setTimeout(() => {
          if (this.listeners.has(listenerId)) {
            listener(this.state, this.state);
          }
        }, 0);
      } catch (error) {
        console.error('[qiankun] Fire immediately error:', error);
      }
    }

    // 返回取消监听函数
    return () => {
      this.listeners.delete(listenerId);
    };
  }

  /**
   * 移除状态变化监听器
   * @param {Function} listener 要移除的监听函数
   */
  offGlobalStateChange(listener) {
    for (const [id, fn] of this.listeners.entries()) {
      if (fn === listener) {
        this.listeners.delete(id);
        break;
      }
    }
  }

  /**
   * 获取当前全局状态
   */
  getGlobalState() {
    return this.deepClone(this.state);
  }

  /**
   * 触发所有监听器
   * @param {Object} prevState 之前的状态
   */
  emit(prevState) {
    const currentState = this.deepClone(this.state);
    
    this.listeners.forEach((listener, id) => {
      try {
        // 使用微任务异步执行,避免阻塞主线程
        Promise.resolve().then(() => {
          if (this.listeners.has(id)) {
            listener(currentState, prevState);
          }
        }).catch(error => {
          console.error(`[qiankun] Listener ${id.toString()} error:`, error);
        });
      } catch (error) {
        console.error(`[qiankun] Listener ${id.toString()} error:`, error);
      }
    });
  }

  /**
   * 深度合并状态
   * @param {Object} target 目标对象
   * @param {Object} source 源对象
   */
  mergeState(target, source) {
    const result = this.deepClone(target);
    
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        const sourceValue = source[key];
        const targetValue = result[key];
        
        if (this.isPlainObject(sourceValue) && this.isPlainObject(targetValue)) {
          // 递归合并对象
          result[key] = this.mergeState(targetValue, sourceValue);
        } else {
          // 直接赋值
          result[key] = this.deepClone(sourceValue);
        }
      }
    }
    
    return result;
  }

  /**
   * 深度克隆对象
   * @param {any} obj 要克隆的对象
   */
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }
    
    if (obj instanceof Date) {
      return new Date(obj.getTime());
    }
    
    if (obj instanceof Array) {
      return obj.map(item => this.deepClone(item));
    }
    
    if (typeof obj === 'object') {
      const clonedObj = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          clonedObj[key] = this.deepClone(obj[key]);
        }
      }
      return clonedObj;
    }
  }

  /**
   * 判断是否为纯对象
   * @param {any} obj 要判断的对象
   */
  isPlainObject(obj) {
    return obj !== null && 
           typeof obj === 'object' && 
           Object.prototype.toString.call(obj) === '[object Object]';
  }

  /**
   * 销毁全局状态管理器
   */
  destroy() {
    this.state = {};
    this.listeners.clear();
    this.initialized = false;
  }
}

// 创建单例实例
let globalStateInstance = null;

function initGlobalState(initialState = {}) {
  if (!globalStateInstance) {
    globalStateInstance = new GlobalState();
  }
  
  return globalStateInstance.initGlobalState(initialState);
}

// 获取全局状态实例(用于调试)
function getGlobalStateInstance() {
  return globalStateInstance;
}

export { initGlobalState, getGlobalStateInstance };

主应用与子应用通信桥梁

主应用中的状态集成
javascript 复制代码
// main-app/src/micro-fe/state-bridge.js
import { initGlobalState } from 'qiankun';

class MainAppStateBridge {
  constructor() {
    this.actions = null;
    this.subApps = new Map();
  }

  // 初始化全局状态
  init(initialState) {
    this.actions = initGlobalState(initialState);
    
    // 监听自身状态变化
    this.actions.onGlobalStateChange((state, prevState) => {
      this.handleMainAppStateChange(state, prevState);
    });
    
    return this.actions;
  }

  // 为子应用创建状态桥接
  createSubAppStateBridge(subAppName) {
    if (!this.actions) {
      throw new Error('Global state not initialized');
    }

    const subAppActions = {
      ...this.actions,
      // 子应用特定的方法
      getSubAppName: () => subAppName,
      // 可以添加子应用级别的状态管理
      setSubAppState: (state) => this.setSubAppState(subAppName, state)
    };

    this.subApps.set(subAppName, {
      actions: subAppActions,
      state: {}
    });

    return subAppActions;
  }

  // 处理主应用状态变化
  handleMainAppStateChange(state, prevState) {
    // 主应用自身的状态响应逻辑
    this.updateMainAppUI(state);
    
    // 记录状态变化日志
    this.logStateChange('main-app', state, prevState);
  }

  // 设置子应用特定状态
  setSubAppState(subAppName, state) {
    const subApp = this.subApps.get(subAppName);
    if (subApp) {
      subApp.state = { ...subApp.state, ...state };
      
      // 可以在这里实现子应用状态与全局状态的某种映射
      this.maybeUpdateGlobalStateFromSubApp(subAppName, state);
    }
  }

  // 可能根据子应用状态更新全局状态
  maybeUpdateGlobalStateFromSubApp(subAppName, state) {
    // 例如:当子应用的用户信息变化时,同步到全局状态
    if (state.user) {
      this.actions.setGlobalState({
        user: state.user,
        lastUpdatedBy: subAppName
      });
    }
  }

  // 更新主应用UI
  updateMainAppUI(state) {
    // 实现主应用界面更新逻辑
    if (state.user) {
      this.updateUserInfo(state.user);
    }
    
    if (state.theme) {
      this.applyTheme(state.theme);
    }
  }

  // 记录状态变化
  logStateChange(source, state, prevState) {
    if (process.env.NODE_ENV === 'development') {
      console.group(`[qiankun] State changed from ${source}`);
      console.log('Previous:', prevState);
      console.log('Current:', state);
      console.groupEnd();
    }
  }
}

// 主应用中使用
export const stateBridge = new MainAppStateBridge();

// 初始化全局状态
export const initAppGlobalState = (initialState) => {
  return stateBridge.init(initialState);
};

// 为子应用提供状态桥接
export const getSubAppStateBridge = (subAppName) => {
  return stateBridge.createSubAppStateBridge(subAppName);
};
子应用状态适配器
javascript 复制代码
// subapp/src/utils/global-state-adapter.js
class GlobalStateAdapter {
  constructor(props) {
    this.props = props;
    this.state = {};
    this.unsubscribe = null;
    this.listeners = new Map();
  }

  // 初始化适配器
  init() {
    if (!this.props || !this.props.onGlobalStateChange) {
      console.warn('[qiankun] Global state not available in sub-app');
      return false;
    }

    // 监听全局状态变化
    this.unsubscribe = this.props.onGlobalStateChange((state, prevState) => {
      this.handleGlobalStateChange(state, prevState);
    }, true); // 立即执行一次获取初始状态

    return true;
  }

  // 处理全局状态变化
  handleGlobalStateChange(state, prevState) {
    const prevLocalState = { ...this.state };
    this.state = state;

    // 通知所有本地监听器
    this.notifyLocalListeners(state, prevState);

    // 执行子应用特定的状态处理
    this.handleSubAppSpecificChanges(state, prevState);

    // 更新子应用UI
    this.updateSubAppUI(state, prevState);
  }

  // 设置全局状态(代理方法)
  setGlobalState(state) {
    if (this.props && this.props.setGlobalState) {
      return this.props.setGlobalState(state);
    }
    return false;
  }

  // 获取当前状态
  getGlobalState() {
    return this.props ? this.props.getGlobalState() : this.state;
  }

  // 注册本地监听器(子应用内部使用)
  onStateChange(callback, immediately = false) {
    const listenerId = Symbol('local-state-listener');
    this.listeners.set(listenerId, callback);

    if (immediately) {
      try {
        callback(this.state, this.state);
      } catch (error) {
        console.error('Local state listener error:', error);
      }
    }

    return () => {
      this.listeners.delete(listenerId);
    };
  }

  // 通知本地监听器
  notifyLocalListeners(state, prevState) {
    this.listeners.forEach((listener, id) => {
      try {
        setTimeout(() => {
          if (this.listeners.has(id)) {
            listener(state, prevState);
          }
        }, 0);
      } catch (error) {
        console.error(`Local listener ${id.toString()} error:`, error);
      }
    });
  }

  // 处理子应用特定的状态变化
  handleSubAppSpecificChanges(state, prevState) {
    // 用户信息变化
    if (state.user !== prevState.user) {
      this.handleUserChange(state.user, prevState.user);
    }

    // 主题变化
    if (state.theme !== prevState.theme) {
      this.handleThemeChange(state.theme);
    }

    // 权限变化
    if (state.user?.permissions !== prevState.user?.permissions) {
      this.handlePermissionChange(state.user?.permissions);
    }
  }

  // 更新子应用UI
  updateSubAppUI(state, prevState) {
    // 实现子应用界面更新逻辑
    // 例如:更新用户信息显示、应用主题等
  }

  // 具体的状态处理函数
  handleUserChange(user, prevUser) {
    console.log('User changed:', { from: prevUser, to: user });
    // 更新用户相关的界面和状态
  }

  handleThemeChange(theme) {
    document.documentElement.setAttribute('data-theme', theme);
  }

  handlePermissionChange(permissions) {
    // 根据新权限更新界面和功能
  }

  // 销毁适配器
  destroy() {
    if (this.unsubscribe) {
      this.unsubscribe();
    }
    this.listeners.clear();
  }
}

// 在子应用中使用
export const createGlobalStateAdapter = (props) => {
  const adapter = new GlobalStateAdapter(props);
  if (adapter.init()) {
    return adapter;
  }
  return null;
};

实际通信流程示例

状态变更传播流程
javascript 复制代码
// 状态变更传播示意图
/**
 * 
 * 主应用 setGlobalState({user: newUser})
 *       ↓
 * GlobalStateManager.notifyListeners()
 *       ↓
 * 主应用监听器 ───→ 子应用A监听器 ───→ 子应用B监听器
 *       ↓               ↓               ↓
 * 更新主应用UI       更新子应用AUI     更新子应用BUI
 * 
 */
具体通信示例
javascript 复制代码
// 通信过程跟踪
class CommunicationTracker {
  constructor() {
    this.messageId = 0;
    this.communicationLog = [];
  }

  trackStateChange(source, target, state, action) {
    const logEntry = {
      id: ++this.messageId,
      timestamp: Date.now(),
      source,
      target,
      state: this.sanitizeState(state),
      action,
      duration: null
    };

    this.communicationLog.push(logEntry);
    
    if (process.env.NODE_ENV === 'development') {
      console.log(`[qiankun-comm] ${source} -> ${target}:`, action, state);
    }

    return logEntry.id;
  }

  markCompletion(messageId, success = true) {
    const entry = this.communicationLog.find(log => log.id === messageId);
    if (entry) {
      entry.duration = Date.now() - entry.timestamp;
      entry.success = success;
    }
  }

  sanitizeState(state) {
    // 移除敏感信息
    const sanitized = { ...state };
    if (sanitized.user) {
      sanitized.user = { ...sanitized.user };
      delete sanitized.user.password;
      delete sanitized.user.token;
    }
    return sanitized;
  }

  getCommunicationStats() {
    const successful = this.communicationLog.filter(log => log.success);
    const failed = this.communicationLog.filter(log => log.success === false);
    
    return {
      total: this.communicationLog.length,
      successful: successful.length,
      failed: failed.length,
      averageDuration: successful.reduce((sum, log) => sum + log.duration, 0) / successful.length,
      recentMessages: this.communicationLog.slice(-10)
    };
  }
}

// 在全局状态管理器中集成跟踪
class TrackedGlobalState extends GlobalState {
  constructor() {
    super();
    this.tracker = new CommunicationTracker();
  }

  setGlobalState(state, overwrite = false) {
    const messageId = this.tracker.trackStateChange(
      'main-app', 
      'all', 
      state, 
      'setGlobalState'
    );

    try {
      const result = super.setGlobalState(state, overwrite);
      this.tracker.markCompletion(messageId, result);
      return result;
    } catch (error) {
      this.tracker.markCompletion(messageId, false);
      throw error;
    }
  }
}

关键特性总结

核心原理

发布-订阅模式:基于事件的通知机制

中心化状态存储:单一数据源

状态隔离:主应用和子应用的状态操作隔离

异步通知:使用微任务避免阻塞

通信机制

状态变更传播:主应用 → 所有监听器(包括子应用)

双向通信:子应用也可以更新全局状态

状态合并:智能合并而不是完全覆盖

错误隔离:单个监听器错误不影响其他监听器

性能优化

懒执行:使用 setTimeout 和 Promise 避免阻塞

深度克隆:确保状态不可变性

内存管理:提供清理和销毁方法

条件监听:支持立即执行和延迟执行

通过这种设计,Qiankun 实现了高效、可靠的主应用与子应用之间的状态通信,同时保持了良好的性能和可维护性。

相关推荐
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税6 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore