小程序网络监控大揭秘:如何实时监听网络变化

小程序网络监控大揭秘:如何实时监听网络变化

前几天写了一篇"5.25秒变0.023秒:小程序图片优化全攻略";介绍了一些小程序图片优化技巧,在文章中提到我们可以借助当前用户的网络状态去加载对应分辨率的图片。下面我们就实现一下这个功能。看之前记得一键三连,先赞后看;月入过万!

需求分析

首先我们需要去写一个下载方法,通过下载来计算请求耗时,然后通过所需耗时来判断网络状态,如果网络状态不好,则进行几次重试,看看是否有更好的网络状态。同时我们还需要使用wx.onNetworkStatusChange这个api来监听网络状态的变化;该api会在用户网络切换时候触发,一旦触发,我们需要重新执行下载方法来判断当前的网络状态。

功能实现

我这里demo使用uni-app开发,所以有些api可能是uni.开头,如果你使用小程序原生开发,换成wx.即可。

新建/utils/networkManager.js,我们先定义一些基本的参数:

js 复制代码
class NetworkManager {
    constructor() {
        // 最大重试次数
        this.MAX_RETRY_COUNT = 3
        // 当前重试次数
        this.retryCount = 0
        // 当前网络状态
        this.currentNetworkStatus = ''
        // 网络状态改变回调
        this.statusChangeCallback = null
        // 图片地址
        this.url = ''
    }
}

然后我们去添加两个函数,用来设置图片地址和网络状态改变的回调函数:

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    /**
     * 设置网络状态变化的回调函数
     * @param {*} callback 
     */
    setChangeCallback(callback) {
        this.statusChangeCallback = callback
    }

    // 设置请求的url
    setRequestUrl(url) {
        this.url = url
    }
}

如何判断当前网络到底好不好呢?我们可以通过uni.downloadFile来下载一张1M-2M大小的图片,通过下载时间来判断网络情况。当请求耗时在1000ms以内,则认为网络极好,如果介于1000-1500ms之间,则认为网络好,如果大于1500ms,则认为网络差。如果网络非常差的时候,我们需要多请求几次,来持续判断网络是否有好转,如果超过我们定义的最大重试次数就停止请求。

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    // 请求方法
    request() {
        return new Promise((resolve, reject) => {
            // 记录当前时间
            const startTime = Date.now()
            uni.downloadFile({
                url: `${this.url}?timer=${startTime}`,
                success: (res) => {
                    // 记录结束时间
                    const endTime = Date.now()
                    // 时间差
                    const duration = endTime - startTime
                    // 判断网络情况
                    this.checkNetworkStatus(duration)
                    resolve(res)
                },
                fail: (res) => {
                    // 进行重试
                    this.retryCount++
                    if (this.retryCount < this.MAX_RETRY_COUNT) {
                        this.request()
                    } else {
                        console.log('网络状态不佳,已停止')
                        // 重试次数归零
                        this.retryCount = 0
                        reject(res)
                    }
                },
            })
        })
    }

    /**
     * 判断网络状态
     * @param {*} duration 请求耗时ms
     */
    checkNetworkStatus(duration) {
        const previousStatus = this.currentNetworkStatus
        if (duration < 1000) {
            this.currentNetworkStatus = 'veryGood'
        } else if (duration >= 1000 && duration <= 1500) {
            this.currentNetworkStatus = 'good'
        } else {
            this.currentNetworkStatus = 'poor'
            // 请求失败,开始判断
            if (this.retryCount < this.MAX_RETRY_COUNT) {
                this.retryCount++
                this.request()
            } else {
                // 达到最大重试次数,停止递归
                this.retryCount = 0
                console.log('网络状态不佳,已停止')
            }
        }

        // 判断网络状态是否发生变化,如果有变化,就通知回调函数
        if (previousStatus !== this.currentNetworkStatus && this.statusChangeCallback) {
            this.statusChangeCallback(this.currentNetworkStatus)
        }
    }
}

最后我们还需要写一个开启函数,用来启动网络监听,同时使用uni.onNetworkStatusChange来监听用户网络环境变化,如果有变化则进行一次请求。

js 复制代码
class NetworkManager {
    constructor() {
        // ...省略
    }
    /**
     * 开启监听
     * @returns 
     */
    start() {
        if (!this.url) {
            console.error('请设置请求的url')
            return
        }
        // 执行请求
        this.request()
        // 网络环境变换后,重新请求
        uni.onNetworkStatusChange(() => {
            this.request()
        })
    }
}

使用方式

我们来看一下最终的使用方式:

js 复制代码
// 使用示例
const networkManager = new NetworkManager()
// 设置请求的url
networkManager.setRequestUrl('https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/wallhaven-o5g125.jpeg')
// 设置网络状态变化的回调函数
networkManager.setChangeCallback((newStatus) => {
    // 这里可以把结果存到全局变量中,在其他页面方便使用
    console.log('网络状态变化:', newStatus)
})
// 启动
networkManager.start()

总结

我们通过uni.downloadFile来下载一张图片,通过下载时间来判断网络情况,然后通过uni.onNetworkStatusChange监听网络环境变化,当网络环境变化时,重新请求;从而去根据网络状态去请求不同大小的资源文件,减少白屏时间,提升用户体验。最后欢迎关注我的专栏前端365,分享前端相关文章,欢迎关注。

往期推荐文章📚

🏷️"5.25秒变0.023秒:小程序图片优化全攻略"

🏷️5分钟get:Uni-App网络请求完美封装指南!

🏷️uni-app开发小程序:项目架构以及经验分享

🏷️小程序TabBar创意动画(文末附完整源代码)

⚠️注意

本文首发于我的博客:lonjin,转载请注明出处。

相关推荐
Myli_ing12 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维29 分钟前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
雯0609~1 小时前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ1 小时前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue