你是否遇到过断网检测的需求?

你也碰到断网检测的需求啦?

一般的断网检测需求,大部分都是在用户网络状态不好或者网络掉线时,我们给用户一个提示或者引导界面,防止用户不知道自己卡了在那里一直等待。

方案1,轮询请求

直接说最有效的方案,我们通过轮训请求来检测网络是否可用,比如加载图片或者访问接口等...

下面我以加载图片为例,搞个小demo:

  1. 首先尽可能的找一个小的图片,不要让图片的请求堵塞我们的其他功能使用。

    推荐一个图片在线的压缩的网站: https://www.yalijuda.com/,然后把图片上到内部的服务器上

  2. 既然搞了,就搞个通用的,使用tsup我们搞个npm包,然后想一想我们要搞的功能,先把入口函数的出入参类型定了。我们既然要做轮训请求图片,我们首先需要一个图片地址,然后请求后的回调事件,甚至可能需要一些控制参数,那我们的入口代码也就有了。

    js 复制代码
    const request = (imgUrl) => {
      // do something
    };
    
    type CheckNetworkOptionsType = {
      interval: number; // 循环时间 单位ms
    };
    
    type CheckNetworkType = (
      imgUrl: string, // 图片url
      callback: (isOnline: boolean) => void,  // 回调,返回网络是否在线
      options?: CheckNetworkOptionsType, // 配置项
    ) => void;
    
    const checkNetwork: CheckNetworkType = (imgUrl, callback, options) => {
      const { interval = 30_000 } = options || {};
      const timer = setInterval(() => {
        request(imgUrl)
      }, interval);
      return timer
    };
    
    export default checkNetwork
  3. 接下来我们要考虑一下如何进行请求,我们需要一个创一个promiseimg标签resove 出去 onloadonerror 对应的在线和离线状态。

    js 复制代码
    const request = (imgUrl) => {
      return new Promise((resolve) => {
        let imgRef = null;
        let isRespond = false;
        imgRef = document.createElement('img');
        imgRef.onerror = () => {
          isRespond = true;
          resolve(false);
          return '';
        };
        imgRef.onload = () => {
          isRespond = true;
          resolve(true);
          return '';
        };
        imgRef.src = `${imgUrl}?time=${new Date().toLocaleString()}`;
    
      });
    };
    
    type CheckNetworkOptionsType = {
      interval: number; // 循环时间 单位ms
    };
    
    type CheckNetworkType = (
      imgUrl: string, // 图片url
      callback: (isOnline: boolean) => void,  // 回调,返回网络是否在线
      options?: CheckNetworkOptionsType, // 配置项
    ) => void;
    
    const checkNetwork: CheckNetworkType = (imgUrl, callback, options) => {
      const { interval = 30_000 } = options || {};
      const timer = setInterval(async () => {
        const status = (await request(imgUrl)) as boolean;
        callback(status);
      }, interval);
      return timer
    };
    
    export default checkNetwork
  4. 这样基本的功能似乎就差不多了,但是感觉好像少点什么?比如服务器就是返回图片资源慢?那我们是不是可以加个超时时间?又或者是不是可以可以让用户手动取消循环?

    js 复制代码
    const request = (imgUrl) => {
      return new Promise((resolve) => {
        let imgRef = null;
        let isRespond = false;
        imgRef = document.createElement('img');
        imgRef.onerror = () => {
          isRespond = true;
          resolve(false);
          return '';
        };
        imgRef.onload = () => {
          isRespond = true;
          resolve(true);
          return '';
        };
        // 加个参数,防止浏览器缓存
        imgRef.src = `${imgUrl}?time=${new Date().toLocaleString()}`;
    
      });
    };
    
    type CheckNetworkOptionsType = {
      interval: number; // 循环时间 单位ms
    };
    
    type CheckNetworkType = (
      imgUrl: string, // 图片url
      callback: (isOnline: boolean) => void,  // 回调,返回网络是否在线
      options?: CheckNetworkOptionsType, // 配置项
    ) => void;
    
    const checkNetwork: CheckNetworkType = (imgUrl, callback, options) => {
      const { interval = 30_000 } = options || {};
      const timer = setInterval(async () => {
        const status = (await request(imgUrl)) as boolean;
        callback(status);
      }, interval);
      return timer
    };
    
    export default checkNetwork
  5. 完整的代码就完整了,具体用的时间还是建议大家关键模块来进行断网检测。不要一个后台配置表单都弄检测,这种完全可以在提交表单的时候接口响应进行处理,断网检测一般都是用在需要实时监控之类的。不多说了,我们来体验下:

6. 没问题,一切ok,发个包,就叫network-watcher吧,欢迎大家star!
github.com/waltiu/netw...

方案2,直接调api

首先说下这种方案不推荐,其一浏览器兼容性有问题,其二只能检测到是否网络有连接,但是不能检测是否可用,这种实用性真的很差。

浏览器也提供了navigator.onLinenavigator.connection 可以直接查询网络状态,我们可以监听网络状态的变化。

js 复制代码
    window.addEventListener('online',function () {
        alert("正常上网");
    })
    window.addEventListener('offline',function () {
        alert('无网络');
    })

这种实用性真的很差,用户网络连接但是没有网或者网很慢,实际上都会影响用户体验!!

用户的体验永远是NO.1

相关推荐
无情的西瓜皮1 天前
MCP 协议实战:从零搭建一个 MCP 服务器(Node.js 版)
vue.js·人工智能·typescript·node.js
退休倒计时1 天前
【每日一题】LeetCode 78. 子集 TypeScript
算法·leetcode·typescript
学习-学习1 天前
Node.js 现在能直接跑 TypeScript 了?Type Stripping 原理、限制与 tsx / ts-node 取舍
typescript·node.js
yume_sibai2 天前
大屏数据可视化 - 边框红绿呼吸灯实现详解
前端·信息可视化·typescript
孟无岐2 天前
LayaAir IDE 插件开发入门:用 TypeScript 给编辑器加一个自己的面板
typescript·游戏开发·工程化·编辑器扩展·layaair·ide 插件
shakingWaves2 天前
better auth worker on cloudflare
typescript·cloudflare·auth·better-auth
退休倒计时3 天前
【每日一题】LeetCode 437. 路径总和 III TypeScript
算法·leetcode·typescript
柯克七七3 天前
给老项目加了 TypeScript,本来只想自己爽,结果全公司代码审查标准被我抬高了
前端·vue.js·typescript
yume_sibai3 天前
高德地图骑行导航 API 介绍与使用方法
前端·typescript
子兮曰4 天前
TypeScript 7.0 RC 深度解读:Go 重写完成,10 倍提速,编译器的「奇点时刻」
前端·后端·typescript