JavaScript系列(41)--状态管理实现详解
JavaScript状态管理实现详解 🔄
今天,让我们深入探讨JavaScript的状态管理实现。状态管理是现代前端应用中的核心概念,它帮助我们有效地管理和同步应用数据。
状态管理基础概念 🌟
💡 小知识:状态管理是一种用于管理应用程序数据流的模式,它通过集中式存储和单向数据流来保持数据的一致性和可预测性。
基本实现 📊
// 1. 简单的状态存储
class SimpleStore {
constructor(initialState = {}) {
this.state = initialState;
this.listeners = new Set();
}
getState() {
return this.state;
}
setState(newState) {
this.state = { ...this.state, ...newState };
this.notify();
}
subscribe(listener) {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
notify() {
this.listeners.forEach(listener => listener(this.state));
}
}
// 2. 支持Action的Store
class ActionStore {
constructor(reducer, initialState = {}) {
this.reducer = reducer;
this.state = initialState;
this.listeners = new Set();
}
dispatch(action) {
this.state = this.reducer(this.state, action);
this.notify();
}
getState() {
return this.state;
}
subscribe(listener) {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
}
notify() {
this.listeners.forEach(listener => listener(this.state));
}
}
// 3. 状态选择器
class StoreSelector {
constructor(store) {
this.store = store;
this.selectors = new Map();
this.cache = new Map();
store.subscribe(() => this.updateSelectors());
}
addSelector(key, selectorFn) {
this.selectors.set(key, selectorFn);
this.updateSelector(key);
}
select(key) {
return this.cache.get(key);
}
updateSelectors() {
this.selectors.forEach((_, key) => this.updateSelector(key));
}
updateSelector(key) {
const selector = this.selectors.get(key);
const state = this.store.getState();
const newValue = selector(state);
if (!this.cache.has(key) || !this.shallowEqual(this.cache.get(key), newValue)) {
this.cache.set(key, newValue);
}
}
shallowEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (!obj1 || !obj2) return false;
return Object.keys(obj1).every(key => obj1[key] === obj2[key]);
}
}
高级功能实现 🚀
// 1. 中间件系统
class MiddlewareStore {
constructor(reducer, initialState = {}) {
this.reducer = reducer;
this.state = initialState;
this.listeners = new Set();
this.middlewares = [];
}
use(middleware) {
this.middlewares.push(middleware);
}
dispatch(action) {
const middlewareAPI = {
getState: () => this.state,
dispatch: (action) => this.dispatch(action)
};
const chain = this.middlewares.map(middleware =>
middleware(middlewareAPI)
);
const composedDispatch = this.compose(...chain)(
this.baseDispatch.bind(this)
);
composedDispatch(action);
}
baseDispatch(action) {
this.state = this.reducer(this.state, action);
this.notify();
}
compose(...funcs) {
if (funcs.length === 0) return arg => arg;
if (funcs.length === 1) return funcs[0];
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
// ... 其他基本方法同ActionStore
}
// 2. 时间旅行调试器
class TimeTravel {
constructor(store) {
this.store = store;
this.history = [{ state: store.getState(), action: '@@INIT' }];
this.currentIndex = 0;
store.subscribe(() => {
if (this.isTimeTraveling) return;
this.history = this.history.slice(0, this.currentIndex + 1);
this.history.push({
state: store.getState(),
action: this.lastAction
});
this.currentIndex = this.history.length - 1;
});
}
recordAction(action) {
this.lastAction = action;
}
undo() {
if (this.currentIndex > 0) {
this.isTimeTraveling = true;
this.currentIndex--;
this.store.setState(this.history[this.currentIndex].state);
this.isTimeTraveling = false;
}
}
redo() {
if (this.currentIndex < this.history.length - 1) {
this.isTimeTraveling = true;
this.currentIndex++;
this.store.setState(this.history[this.currentIndex].state);
this.isTimeTraveling = false;
}
}
getHistory() {
return this.history;
}
jumpTo(index) {
if (index >= 0 && index < this.history.length) {
this.isTimeTraveling = true;
this.currentIndex = index;
this.store.setState(this.history[index].state);
this.isTimeTraveling = false;
}
}
}
// 3. 状态持久化
class PersistentStore {
constructor(store, options = {}) {
this.store = store;
this.options = {
key: 'app_state',
storage: localStorage,
serialize: JSON.stringify,
deserialize: JSON.parse,
...options
};
this.init();
}
init() {
// 加载持久化的状态
const savedState = this.options.storage.getItem(this.options.key);
if (savedState) {
try {
const state = this.options.deserialize(savedState);
this.store.setState(state);
} catch (error) {
console.error('Failed to load persisted state:', error);
}
}
// 订阅状态变化
this.store.subscribe(() => this.persist());
}
persist() {
try {
const state = this.store.getState();
const serialized = this.options.serialize(state);
this.options.storage.setItem(this.options.key, serialized);
} catch (error) {
console.error('Failed to persist state:', error);
}
}
clear() {
this.options.storage.removeItem(this.options.key);
}
}
性能优化技巧 ⚡
// 1. 批量更新优化
class BatchUpdateStore {
constructor(initialState = {}) {
this.state = initialState;
this.listeners = new Set();
this.pendingUpdates = new Map();
this.isUpdating = false;
}
setState(key, value) {
this.pendingUpdates.set(key, value);
this.scheduleBatchUpdate();
}
scheduleBatchUpdate() {
if (!this.isUpdating) {
this.isUpdating = true;
Promise.resolve().then(() => this.processBatchUpdate());
}
}
processBatchUpdate() {
const newState = { ...this.state };
this.pendingUpdates.forEach((value, key) => {
newState[key] = value;
});
this.state = newState;
this.pendingUpdates.clear();
this.isUpdating = false;
this.notify();
}
}
// 2. 选择器优化
class MemoizedSelector {
constructor() {
this.cache = new Map();
this.lastArgs = new Map();
}
createSelector(dependencies, combiner) {
return (...args) => {
const key = JSON.stringify(args);
const depValues = dependencies.map(dep => dep(...args));
// 检查依赖是否改变
if (this.shouldUpdate(key, depValues)) {
const result = combiner(...depValues);
this.cache.set(key, result);
this.lastArgs.set(key, depValues);
}
return this.cache.get(key);
};
}
shouldUpdate(key, newArgs) {
if (!this.cache.has(key)) return true;
const lastArgs = this.lastArgs.get(key);
return !lastArgs || !this.shallowEqual(lastArgs, newArgs);
}
shallowEqual(arr1, arr2) {
return arr1.length === arr2.length &&
arr1.every((item, index) => item === arr2[index]);
}
}
// 3. 状态分片
class SlicedStore {
constructor() {
this.slices = new Map();
this.listeners = new Map();
}
createSlice(name, reducer, initialState) {
if (this.slices.has(name)) {
throw new Error(`Slice ${name} already exists`);
}
this.slices.set(name, {
state: initialState,
reducer
});
this.listeners.set(name, new Set());
}
dispatch(sliceName, action) {
const slice = this.slices.get(sliceName);
if (!slice) {
throw new Error(`Slice ${sliceName} not found`);
}
const newState = slice.reducer(slice.state, action);
if (newState !== slice.state) {
slice.state = newState;
this.notifySliceListeners(sliceName);
}
}
subscribe(sliceName, listener) {
const listeners = this.listeners.get(sliceName);
if (!listeners) {
throw new Error(`Slice ${sliceName} not found`);
}
listeners.add(listener);
return () => listeners.delete(listener);
}
notifySliceListeners(sliceName) {
const listeners = this.listeners.get(sliceName);
const state = this.slices.get(sliceName).state;
listeners.forEach(listener => listener(state));
}
}
最佳实践建议 💡
- 状态设计模式
// 1. 状态隔离
class IsolatedStore {
constructor() {
this.stores = new Map();
}
createStore(name, initialState) {
if (this.stores.has(name)) {
throw new Error(`Store ${name} already exists`);
}
const store = new SimpleStore(initialState);
this.stores.set(name, store);
return store;
}
getStore(name) {
const store = this.stores.get(name);
if (!store) {
throw new Error(`Store ${name} not found`);
}
return store;
}
}
// 2. 状态同步
class SyncedStore {
constructor(stores) {
this.stores = stores;
this.syncListeners = new Map();
}
sync(sourceStore, targetStore, mapper) {
const unsubscribe = sourceStore.subscribe(state => {
const mappedState = mapper(state);
targetStore.setState(mappedState);
});
this.syncListeners.set(
`${sourceStore.name}-${targetStore.name}`,
unsubscribe
);
}
unsync(sourceStore, targetStore) {
const key = `${sourceStore.name}-${targetStore.name}`;
const unsubscribe = this.syncListeners.get(key);
if (unsubscribe) {
unsubscribe();
this.syncListeners.delete(key);
}
}
}
// 3. 状态验证
class ValidatedStore {
constructor(schema) {
this.schema = schema;
this.store = new SimpleStore();
}
setState(newState) {
const validationResult = this.validateState(newState);
if (validationResult.isValid) {
this.store.setState(newState);
} else {
throw new Error(
`Invalid state: ${validationResult.errors.join(', ')}`
);
}
}
validateState(state) {
const errors = [];
let isValid = true;
Object.entries(this.schema).forEach(([key, validator]) => {
if (!validator(state[key])) {
isValid = false;
errors.push(`Invalid value for ${key}`);
}
});
return { isValid, errors };
}
}
结语 📝
状态管理是现代JavaScript应用中的核心概念,通过本文,我们学习了:
- 状态管理的基本概念和实现
- 高级功能如中间件和时间旅行
- 性能优化技巧
- 最佳实践和设计模式
- 状态验证和同步策略
💡 学习建议:在实践中,要根据应用的规模和复杂度选择合适的状态管理方案。对于小型应用,简单的状态存储就足够了;对于大型应用,则需要考虑使用更完整的状态管理解决方案。
如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇
终身学习,共同成长。
咱们下一期见
💻