2023开发中遇到的问题

300 阅读5分钟

Vue 异常处理

1、全局错误处理:Vue.config.errorHandler

Vue.config.errorHandler = function(err, vm, info) {};

如果在组件渲染时出现运行错误,错误将会被传递至全局Vue.config.errorHandler 配置函数 (如果已设置)。

比如前端监控领域的 sentry,就是利用这个钩子函数进行的 vue 相关异常捕捉处理

2、全局警告处理Vue.config.warnHandler

Vue.config.warnHandler = function(msg, vm, trace) {};
复制代码

注意:仅在开发环境生效

像在模板中引用一个没有定义的变量,它就会有warning

3、单个vue 实例错误处理renderError

const app = new Vue({
    el: "#app",
    renderError(h, err) {
        return h("pre", { style: { color: "red" } }, err.stack);
    }
});
复制代码

和组件相关,只适用于开发环境,这个用处不是很大,不如直接看控制台

4、子孙组件错误处理errorCaptured

Vue.component("cat", {
    template: `<div><slot></slot></div>`,
    props: { name: { type: string } },
    errorCaptured(err, vm, info) {
        console.log(`cat EC: ${err.toString()}\ninfo: ${info}`);
        return false;
    }
});
复制代码

注:只能在组件内部使用,用于捕获子孙组件的错误,一般可以用于组件开发过程中的错误处理

5、终极错误捕捉window.onerror

window.onerror = function(message, source, line, column, error) {};
复制代码

它是一个全局的异常处理函数,可以抓取所有的 JavaScript 异常

模块化

1. CommonJS 实现模块化 CommonJS 是的 NodeJS 所使用的一种服务端的模块化规范,它将每一个文件定义为一个 module ,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中
3.1 所有代码都运行于模块作用域,不会污染全局。
3.2 使用同步的方式加载,也就是说,只有加载完成才能执行后面的操作,这点和 AMD 不同,由于 CommonJS 的模块化是用在 Node 端也就是服务端,模块加载的时间损耗只是磁盘读取,这个加载速度是很快的,所以可以使用同步的方式。
3.4 CommonJS 支持动态导入的方式,,比如:require(./${path}.js)
3.5 模块可以多次加载,但是只会在第一次加载时运行一次,然后加载结果会被缓存,后面再次加载会直接读取缓存结果,如果想让模块重新执行,就必须清除缓存。
3.6 CommonJS 模块输出的是一个** 值的拷贝,**
3.7 模块的加载顺序,按照其在代码中出现的顺序。 1. ESModule 实现的模块化
ESModule 是 ES6 提供的官方 js 模块化方案。目前浏览器还不能全面支持 ESModule 的语法,需要用 babel 进行解析。
ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";
ESModule 导出的模块是只读的,不能变更,否则报错,对象可以修改引用
ESModule 输出的是值的引用
ESModule 的模块化是静态的,和 CommonJS 不同,ESModule 模块不是对象,而是通过 export 命令显示输出的指定代码的片段,再通过 import 命令将代码命令输入。也就是说在编译阶段就需要确定模块之间的依赖关系,这一点不同于 AMD / CMD / CommonJS ,这三者都是在运行时确定模块间的依赖关系的。

websocket 心跳检测

心跳检测步骤
1 客户端每隔一个时间间隔发生一个探测包给服务器
2 客户端发包时启动一个超时定时器
3 服务器端接收到检测包,应该回应一个包
4 如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
5 如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了

var socket; //websocket的实例
var lockReconnect = false; //避免重复连接
getwebsocket();
function getwebsocket() { //新建websocket的函数 页面初始化 断开连接时重新调用
    var wsUrl = 'ws://192.168.0.147:8080/api/v1/socket/order/wGk86yE7MShsN3DM2Q5m7t2NEzPS5zmE1634897413404' + window.token + '&djxh=' + window.djxh;
    socket = new WebSocket(wsUrl);
    socket.onerror = function(event) {
        console.log('websocket服务出错了');
        reconnect(wsUrl);
    };
    socket.onclose = function(event) {
        console.log('websocket服务关闭了');
        reconnect(wsUrl);
    };
    socket.onopen = function(event) {
        console.log('websocket连接成功');
        heartCheck.reset().start(); //传递信息
    };
    socket.onmessage = function(event) {
        //如果获取到消息,心跳检测重置
        //拿到任何消息都说明当前连接是正常的
        console.log('websocket服务获得数据了');
        //接受消息后的UI变化
        doWithMsg(event.data);
        heartCheck.reset().start();
    };
    //收到消息推送 如果处理他
    function doWithMsg(msg) {
        // getdjxh()//这个函数是业务上面申请列表的函数 可以忽略
        // window.external.CallFun('receiveMsg');//这个也是
    }
}
 
//重连
function reconnect(url) {
    if (lockReconnect) return;
    lockReconnect = true;
    //没连接上会一直重连,设置延迟避免请求过多
    setTimeout(function() {
        getwebsocket();
        lockReconnect = false;
    }, 2000);
}
 
//心跳检测
var heartCheck = {
    timeout: 5000, //5秒,针对不同项目设置不同时间,比如客服系统就不用那么频繁检测,股票交易所就必须很频繁
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function() {
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function() {
        var self = this;
        this.timeoutObj = setTimeout(function() {
            //这里发送一个心跳,后端收到后,返回一个心跳消息,
            //onmessage拿到返回的心跳就说明连接正常
            socket.send("心跳测试");//发送这个消息的时候,必须让后端收到消息后,立马发送一个消息,这样来回一个接收过程,就可以判断当前还没有断开连接。
            self.serverTimeoutObj = setTimeout(function() { //如果超过一定时间还没重置,说明后端主动断开了
                socket.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    }
}