#网络状态通鉴:统一封装与监听之道

126 阅读5分钟

文/ 天机阁网络护法

(虚空之中,青袍修士手持「网络状态罗盘」,罗盘闪烁着五色灵光)

"今日传授尔等网络状态监听大法。须知网络如潮汐,时强时弱,需以统一之道驾驭方能处变不惊。"


第一章:网络五方大阵

原生API监听(中央戊己土)

// 乾坤网络状态监听大法
function initNativeListener() {
    window.addEventListener('online', () => {
        updateNetworkStatus({ online: true, type: 'unknown' });
    });

    window.addEventListener('offline', () => {
        updateNetworkStatus({ online: false, type: 'none' });
    });
}

定时轮询检测(东方甲乙木)

// 青木轮询检测术
function startPollingCheck(interval = 3000) {
    setInterval(async () => {
        const online = await checkNetworkConnectivity();
        updateNetworkStatus({ 
            online,
            type: online ? 'polling-confirmed' : 'polling-failed'
        });
    }, interval);
}

混合事件监听(南方丙丁火)

// 离火混合监听阵
function setupHybridListener() {
    // 原生事件打底
    initNativeListener();
    
    // 定时校验防漏报
    startPollingCheck();
    
    // WebSocket心跳验证
    setupWebSocketHeartbeat();
}

网络质量评估(西方庚辛金)

// 庚金网络质量鉴定术
async function evaluateNetworkQuality() {
    const start = performance.now();
    const res = await fetch('/ping', { cache: 'no-store' });
    const latency = performance.now() - start;
    const speed = res.headers.get('content-length') / (latency / 1000);
    
    return {
        latency: Math.round(latency),
        speed: Math.round(speed),
        rating: latency < 500 ? 'good' : 'poor'
    };
}

离线缓存处理(北方壬癸水)

// 玄水离线缓存诀
class OfflineCache {
    constructor() {
        this.queue = [];
        this.isOnline = navigator.onLine;
    }

    addRequest(request) {
        if (this.isOnline) {
            return fetch(request);
        } else {
            this.queue.push(request);
            return Promise.reject(new Error('Queued for offline processing'));
        }
    }

    flush() {
        while (this.queue.length) {
            const request = this.queue.shift();
            fetch(request.clone());
        }
    }
}

第二章:统一封装七式

第一式:铸就灵基(核心类封装)

class NetworkMonitor {
    constructor() {
        this.status = {
            online: navigator.onLine,
            type: navigator.onLine ? 'initial' : 'offline',
            lastChanged: Date.now()
        };
        this.listeners = new Set();
    }
}

第二式:布设感应(多维度检测)

// 五行网络检测阵
function setupDetection() {
    // 基础事件监听
    window.addEventListener('online', this.handleOnline.bind(this));
    window.addEventListener('offline', this.handleOffline.bind(this));
    
    // 定时心跳检测
    this.heartbeatTimer = setInterval(() => {
        this.checkByHeartbeat();
    }, 10000);
    
    // 请求拦截监控
    this.setupRequestInterceptor();
}

第三式:凝练状态(统一状态管理)

// 太极网络状态模型
function updateNetworkState(newState) {
    const prevState = this.status;
    this.status = {
        ...prevState,
        ...newState,
        lastChanged: newState.online !== prevState.online ? Date.now() : prevState.lastChanged
    };
    
    this.notifyListeners();
}

第四式:广布监听(观察者模式)

// 天听地视大法
function addListener(callback) {
    this.listeners.add(callback);
    // 立即返回当前状态
    callback(this.status);
}

function notifyListeners() {
    this.listeners.forEach(cb => cb(this.status));
}

第五式:容错处理(自动恢复)

// 不灭金身诀
function handleConnectionRecovery() {
    let retries = 0;
    const maxRetries = 5;
    
    const checkRecovery = async () => {
        const online = await this.testConnection();
        if (!online && retries < maxRetries) {
            retries++;
            setTimeout(checkRecovery, 1000 * Math.pow(2, retries));
            return;
        }
        
        if (online) {
            this.updateNetworkState({ online: true, type: 'recovered' });
        }
    };
}

第六式:性能优化(节流防抖)

// 九转节流术
function createOptimizedHandler() {
    let lastUpdate = 0;
    const minInterval = 2000; // 2秒内状态变化只通知一次
    
    return (newStatus) => {
        const now = Date.now();
        if (now - lastUpdate > minInterval || 
            newStatus.online !== this.status.online) {
            this.updateNetworkState(newStatus);
            lastUpdate = now;
        }
    };
}

第七式:多端同步(状态共享)

// 分光化影术
function syncAcrossTabs() {
    // 通过localStorage同步不同标签页状态
    window.addEventListener('storage', (event) => {
        if (event.key === 'network-status') {
            const newStatus = JSON.parse(event.newValue);
            this.updateNetworkState(newStatus);
        }
    });
    
    // 当前状态变化时广播
    this.onStatusChange((status) => {
        localStorage.setItem('network-status', JSON.stringify(status));
    });
}

第三章:完整实现

网络状态监控至尊版

class UltimateNetworkMonitor {
    constructor(options = {}) {
        this.options = {
            heartbeatUrl: '/network-test',
            heartbeatInterval: 15000,
            ...options
        };
        
        this.status = {
            online: navigator.onLine,
            type: navigator.onLine ? 'initial' : 'offline',
            lastChanged: Date.now(),
            latency: null,
            speed: null
        };
        
        this.listeners = new Set();
        this.setupDetection();
    }

    // 核心检测方法
    setupDetection() {
        // 基础事件监听
        window.addEventListener('online', this.handleOnline.bind(this));
        window.addEventListener('offline', this.handleOffline.bind(this));
        
        // 定时心跳检测
        this.startHeartbeat();
        
        // 请求拦截监控
        this.setupRequestWatch();
        
        // 跨标签页同步
        this.setupCrossTabSync();
    }
    
    // 心跳检测实现
    startHeartbeat() {
        this.heartbeatTimer = setInterval(async () => {
            try {
                const start = Date.now();
                const res = await fetch(this.options.heartbeatUrl, {
                    method: 'HEAD',
                    cache: 'no-store'
                });
                
                const latency = Date.now() - start;
                const speed = res.headers.get('content-length') / (latency / 1000);
                
                this.updateStatus({
                    online: true,
                    type: 'heartbeat-confirmed',
                    latency,
                    speed
                });
            } catch (error) {
                this.updateStatus({
                    online: false,
                    type: 'heartbeat-failed'
                });
            }
        }, this.options.heartbeatInterval);
    }
    
    // 状态更新统一入口
    updateStatus(newState) {
        const prevOnline = this.status.online;
        this.status = {
            ...this.status,
            ...newState,
            lastChanged: newState.online !== prevOnline ? Date.now() : this.status.lastChanged
        };
        
        this.notifyListeners();
    }
    
    // 观察者模式实现
    addListener(callback) {
        this.listeners.add(callback);
        callback(this.status);
        return () => this.listeners.delete(callback);
    }
    
    notifyListeners() {
        this.listeners.forEach(cb => cb(this.status));
    }
    
    // 销毁方法
    destroy() {
        clearInterval(this.heartbeatTimer);
        window.removeEventListener('online', this.handleOnline);
        window.removeEventListener('offline', this.handleOffline);
        this.listeners.clear();
    }
}

第四章:应用心法

网络状态五要诀

1️⃣ 统一入口 - 所有状态变更通过单一方法处理
2️⃣ 多维检测 - 结合事件监听与主动探测
3️⃣ 性能优化 - 合理设置检测频率和方式
4️⃣ 状态持久 - 保持状态一致性
5️⃣ 扩展灵活 - 支持自定义检测策略

React Hook 示例

import { useEffect, useState } from 'react';

export function useNetworkStatus() {
    const [status, setStatus] = useState({
        online: navigator?.onLine ?? true,
        type: 'initial'
    });
    
    useEffect(() => {
        const monitor = new UltimateNetworkMonitor();
        const removeListener = monitor.addListener(setStatus);
        
        return () => {
            removeListener();
            monitor.destroy();
        };
    }, []);
    
    return status;
}

Vue Composition API 示例

import { ref, onMounted, onUnmounted } from 'vue';

export function useNetwork() {
    const networkStatus = ref({
        online: window.navigator.onLine,
        type: 'initial'
    });
    
    let monitor;
    
    onMounted(() => {
        monitor = new UltimateNetworkMonitor();
        monitor.addListener(status => {
            networkStatus.value = status;
        });
    });
    
    onUnmounted(() => {
        monitor?.destroy();
    });
    
    return { networkStatus };
}

第五章:进阶技巧

网络类型检测

// 五行网络类型辨别术
async function detectConnectionType() {
    try {
        const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
        if (connection) {
            return {
                type: connection.type || 'unknown',
                effectiveType: connection.effectiveType || 'unknown',
                downlink: connection.downlink || 0,
                rtt: connection.rtt || 0
            };
        }
        
        // 备用检测方案
        const speedTest = await testNetworkSpeed();
        return {
            type: speedTest.speed > 5 ? 'wifi' : 'cellular',
            effectiveType: estimateEffectiveType(speedTest.latency, speedTest.speed),
            ...speedTest
        };
    } catch (e) {
        return { type: 'unknown' };
    }
}

请求队列管理

// 天罡请求队列
class NetworkAwareQueue {
    constructor() {
        this.queue = [];
        this.isOnline = true;
        this.monitor = new UltimateNetworkMonitor();
        this.monitor.addListener(({ online }) => {
            this.isOnline = online;
            if (online) this.processQueue();
        });
    }
    
    add(request) {
        return new Promise((resolve, reject) => {
            const task = { request, resolve, reject };
            this.queue.push(task);
            if (this.isOnline) this.processQueue();
        });
    }
    
    async processQueue() {
        while (this.queue.length > 0 && this.isOnline) {
            const task = this.queue.shift();
            try {
                const response = await fetch(task.request);
                task.resolve(response);
            } catch (error) {
                if (!this.isOnline) {
                    this.queue.unshift(task);
                    break;
                }
                task.reject(error);
            }
        }
    }
}

网络变化预测

// 太乙预测神数
function predictNetworkDowntime() {
    const history = loadNetworkHistory(); // 加载历史网络状态记录
    const patterns = analyzePatterns(history);
    
    // 基于时间模式预测
    const now = new Date();
    const timeBasedRisk = patterns.timeBased[now.getHours()] || 0;
    
    // 基于持续时间的预测
    const currentDuration = Date.now() - this.status.lastChanged;
    const durationRisk = currentDuration > 3600000 ? 0.2 : 0; // 在线超过1小时风险增加
    
    return Math.min(timeBasedRisk + durationRisk, 0.9); // 最大返回90%概率
}

(突然罗盘剧烈震动,显示网络异常)

弟子:"师尊!网络状态频繁波动!"

修士:"莫慌!此乃修炼良机,看我'稳如泰山'诀!"

修士手掐法诀,祭出稳定代码:

function createStableDetector() {
    let lastTrueStatus = null;
    const requiredStableCount = 3;
    let stableCount = 0;
    
    return (currentStatus) => {
        if (lastTrueStatus === currentStatus) {
            stableCount++;
        } else {
            stableCount = 0;
            lastTrueStatus = currentStatus;
        }
        
        return stableCount >= requiredStableCount ? currentStatus : null;
    };
}

// 使用示例
const stableDetector = createStableDetector();
monitor.addListener((status) => {
    const stableStatus = stableDetector(status.online);
    if (stableStatus !== null) {
        updateUI(stableStatus);
    }
});

网络大道真言:

当网络监听修炼至化境,可:

  • 预知网络变化
  • 无缝切换连接方式
  • 智能预加载关键资源
  • 精准评估网络质量

(修士化作流光融入罗盘,浮现终极奥义)

"记住,网络之道,在于'感知而不打扰'。如同春风化雨,润物无声......"

<罗盘展开,显现完整网络状态知识图谱> <第二元神显化:关注天机阁,解锁更多前端秘法>