JavaScript高级技巧:构建零依赖实时数据同步系统
一、系统架构设计
数据变更 → 操作转换 → 状态同步 → 冲突解决 → 最终一致性
二、核心功能实现
1. 操作转换引擎
class OperationTransformer {
constructor() {
this.operations = [];
}
applyOperation(op) {
// 转换新操作以考虑现有操作
const transformedOp = this.transformOperation(op);
this.operations.push(transformedOp);
return transformedOp;
}
transformOperation(newOp) {
return this.operations.reduce((op, existingOp) => {
if (op.type === 'insert' && existingOp.type === 'insert') {
return this.transformII(op, existingOp);
}
if (op.type === 'delete' && existingOp.type === 'delete') {
return this.transformDD(op, existingOp);
}
return this.transformID(op, existingOp);
}, newOp);
}
transformII(newInsert, existingInsert) {
// 处理两个插入操作的冲突
if (newInsert.position <= existingInsert.position) {
return newInsert;
}
return {
...newInsert,
position: newInsert.position + existingInsert.text.length
};
}
}
2. WebSocket同步层
class SyncClient {
constructor(url) {
this.ws = new WebSocket(url);
this.queue = [];
this.connected = false;
this.ws.onopen = () => {
this.connected = true;
this.flushQueue();
};
this.ws.onmessage = (event) => {
const message = JSON.parse(event.data);
this.handleRemoteOperation(message);
};
}
sendOperation(op) {
if (this.connected) {
this.ws.send(JSON.stringify(op));
} else {
this.queue.push(op);
}
}
flushQueue() {
while (this.queue.length > 0) {
this.sendOperation(this.queue.shift());
}
}
handleRemoteOperation(remoteOp) {
// 处理来自其他客户端的操作
document.dispatchEvent(
new CustomEvent('remoteOperation', { detail: remoteOp })
);
}
}
3. 客户端状态管理
class DocumentState {
constructor() {
this.text = '';
this.revision = 0;
this.pendingOperations = [];
}
applyOperation(op) {
switch (op.type) {
case 'insert':
this.text = this.text.slice(0, op.position) +
op.text +
this.text.slice(op.position);
break;
case 'delete':
this.text = this.text.slice(0, op.position) +
this.text.slice(op.position + op.length);
break;
}
this.revision++;
}
addPendingOperation(op) {
this.pendingOperations.push(op);
}
confirmOperation(op) {
this.pendingOperations = this.pendingOperations.filter(
pending => pending.id !== op.id
);
}
}
三、高级功能实现
1. 冲突解决策略
class ConflictResolver {
static resolve(localState, remoteOp) {
// 查找未确认的本地操作
const conflictingOps = localState.pendingOperations.filter(
op => this.operationsOverlap(op, remoteOp)
);
// 按操作时间戳排序
const sortedOps = [...conflictingOps, remoteOp].sort(
(a, b) => a.timestamp - b.timestamp
);
// 重新应用操作
let result = localState.text;
sortedOps.forEach(op => {
result = this.applySingleOperation(result, op);
});
return result;
}
static operationsOverlap(op1, op2) {
// 判断两个操作是否影响相同文本范围
}
}
2. 离线同步支持
class OfflineManager {
constructor() {
this.pendingChanges = [];
this.storageKey = 'unsyncedChanges';
this.loadChanges();
}
addChange(change) {
this.pendingChanges.push(change);
this.saveChanges();
}
getChanges() {
return [...this.pendingChanges];
}
clearChanges() {
this.pendingChanges = [];
localStorage.removeItem(this.storageKey);
}
loadChanges() {
const saved = localStorage.getItem(this.storageKey);
if (saved) {
this.pendingChanges = JSON.parse(saved);
}
}
saveChanges() {
localStorage.setItem(
this.storageKey,
JSON.stringify(this.pendingChanges)
);
}
}
四、实战案例演示
1. 主应用集成
class CollaborativeEditor {
constructor(textarea, wsUrl) {
this.textarea = textarea;
this.state = new DocumentState();
this.transformer = new OperationTransformer();
this.syncClient = new SyncClient(wsUrl);
this.offlineManager = new OfflineManager();
this.setupEventListeners();
}
setupEventListeners() {
this.textarea.addEventListener('input', (e) => {
const op = this.createOperationFromInput(e);
this.state.applyOperation(op);
this.transformer.applyOperation(op);
this.syncClient.sendOperation(op);
});
document.addEventListener('remoteOperation', (e) => {
const resolved = ConflictResolver.resolve(
this.state, e.detail
);
this.textarea.value = resolved;
this.state.text = resolved;
});
}
}
2. 性能优化方案
- 操作压缩:合并连续相同操作
- 增量同步:只发送差异部分
- 本地优先:优先响应本地操作
- 批量确认:减少网络请求

