【javascript】ES6模块化封装
阅读: 147 回复: 1

发布于:2020-9-20

问题描述

用ES6模块化封装 但是由于基础差 底子薄 不会模块化 现在只是普通到倒入.

我想了解下,模块化的设计思想是啥。如何发现模块,他的特性有哪些,如何将我这段代码

进行模块化封装?

模板源码:

<template>
<div>
pad控制端
Welcome
<br />
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</div>
</template>

<script>
import socket from "./socket";//导入socket
export default {
name: "Remote"
};
</script>

<style scoped lang="less">
.Remote {
}
</style>

javascript代码:

var websocket = null;
var wsGroupId = "20191009170924631538723061895168";
var type = "screenA"
var url = "ws://192.168.50.174:8011/ws/" + wsGroupId + "/" + type;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket(url);
} else {
alert('Not support websocket')
}

//连接发生错误的回调方法
websocket.onerror = function() {
// setMessageInnerHTML("error");
console.log(getNowTime() + ' 发生异常了');
reconnect(url);
};

//连接成功建立的回调方法
websocket.onopen = function(event) {
//setMessageInnerHTML("open");
console.log(getNowTime() + " Socket 已打开");
send("heartbeat");
//心跳检测重置
heartCheck.start()
}

//接收到消息的回调方法
websocket.onmessage = function(event) {
//websocket.setMessageInnerHTML(event.data);
// 维持心跳
heartCheck.start();
if (event.data != 'heartbeat') {
document.getElementById("text").value = event.data;
console.log(event.data)
}
//window.location.href="http://www.jb51.net";
}

//连接关闭的回调方法
websocket.onclose = function() {
// websocket.setMessageInnerHTML("close");
console.log(getNowTime() + " Socket已关闭");
reconnect(url)
}

// //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
// window.onbeforeunload = function(){
// websocket.close();
// }

//将消息显示在网页上
// function setMessageInnerHTML(innerHTML){
// document.getElementById('message').innerHTML += innerHTML + '<br/>';
// }

//关闭连接
// function closeWebSocket(){
// websocket.close();
// lockReconnect= false;
// reconnect(url);
// }

//发送消息
function send(message) {
// var message = document.getElementById('text').value;
websocket.send(message);
}

var lockReconnect = false; //避免重复连接
//重试连接socket
function reconnect(url) {
if (lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function() {
createWebSocket(url);
lockReconnect = false;
}, 10000);
}
//心跳检测
var heartCheck = {
timeout: 5000,
timeoutObj: null,
serverTimeoutObj: null,
start: function() {
console.log(getNowTime() + " Socket 心跳检测");
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function() {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
console.log(getNowTime() + ' Socket 连接重试');
send("heartbeat");
self.serverTimeoutObj = setTimeout(function() {
console.log(this);
close();
}, self.timeout);
}, this.timeout)
}
}

/**
* 获取系统当前时间
* @returns
*/
function p(s) {
return s < 10 ? '0' + s : s;
}

function getNowTime() {
var myDate = new Date();
//获取当前年
var year = myDate.getFullYear();
//获取当前月
var month = myDate.getMonth() + 1;
//获取当前日
var date = myDate.getDate();
var h = myDate.getHours(); //获取当前小时数(0-23)
var m = myDate.getMinutes(); //获取当前分钟数(0-59)
var s = myDate.getSeconds();
return year + '-' + p(month) + "-" + p(date) + " " + p(h) + ':' + p(m) + ":" + p(s);
}



解决方案

要了解模块化设计思想,可以看看我之前写的对模块化设计思想的总结文章地址: 

模块化设计思想一文


首先我们来分析下以上代码不足的地方:

1. 面向过程的思维模式,没有考虑其复用性,代码组织凌乱。

2. 整个代码块职责划分不清晰,核心功能与辅助功能混杂在一起,影响代码的理解。

3. 代码命名不规范,例如 input消息输入框 id取个 text, message是不是会更好,一定要语义化清晰

4. 尽量使用es6的语法让代码变得清晰精简,减少代码量。

5. 全局变量污染,例如:  tt = setTimeout(function() {, 全局变量会使作用域链边长,影响

性能,也会带来安全隐患,比如A模块块定义的全局变量,B模块无意间修改了,就会产生错误

bug。

 

良好的代码应该:

1.  使用面向对象的思维模式组织代码,这样易于阅读,代码块需要按照概念进行就近原则组织。

2.  按照代码的功能职责进行划分模块,保证,单一功能职责。

3.  命名一定要有语义化,代码不仅仅是给机器执行的还要给人阅读。

4.  es6的语法让代码在阅读的时候更加简洁,清晰,尽量使用他。

5.  减少全局变量的使用,如果真的要用,一定要统一管理起来,然后采用命名空间的方式进行隔离

    例如  JQuery的这种方式更好。


在不改变以上代码的功能的前提下进行封装重构:

utils.js
export default {
/**
* 获取系统当前时间
* @returns
*/
p(s) {
return s < 10 ? '0' + s : s;
},
getNowTime() {
var myDate = new Date();
//获取当前年
var year = myDate.getFullYear();
//获取当前月
var month = myDate.getMonth() + 1;
//获取当前日
var date = myDate.getDate();
var h = myDate.getHours(); //获取当前小时数(0-23)
var m = myDate.getMinutes(); //获取当前分钟数(0-59)
var s = myDate.getSeconds();
return year + '-' + p(month) + "-" + p(date) + " " + p(h) + ':' + p(m) + ":" + p(s);
}
}

heartCheck.js
export default {
timeout: 5000,
timeoutObj: null,
serverTimeoutObj: null,
start: function() {
console.log(getNowTime() + " Socket 心跳检测");
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function() {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
console.log(getNowTime() + ' Socket 连接重试');
send("heartbeat");
self.serverTimeoutObj = setTimeout(function() {
console.log(this);
close();
}, self.timeout);
}, this.timeout)
}
}

websocket.js
export default {
websocket: null,
lockReconnect:false,
openConnect() {
if ('WebSocket' in window) {
this.websocket = new WebSocket(url);
} else {
alert('Not support websocket')
}
},
reconnect(url) {
if (lockReconnect) {
return;
};
lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
tt && clearTimeout(tt);
tt = setTimeout(function() {
createWebSocket(url);
lockReconnect = false;
}, 10000);
},
buildHook() {
//连接发生错误的回调方法
this.websocket.onerror = function() {
reconnect(url);
};

//连接成功建立的回调方法
this.websocket.onopen = function(event) {
send("heartbeat");
heartCheck.start()
}

//接收到消息的回调方法
this.websocket.onmessage = function(event) {
// 维持心跳
heartCheck.start();
if (event.data != 'heartbeat') {
document.getElementById("text").value = event.data;
console.log(event.data);
}
}
//连接关闭的回调方法
this.websocket.onclose = function() {
console.log(getNowTime() + " Socket已关闭");
reconnect(url);
}

},
init(url) {
this.openConnect();//第一步建立链接
this.buildHook(); //第二步 组织钩子函数
}
}


代码大致做了重构,主要是给你一做一个模板,让你理解模块化如何去做,可以按照以上例子来封装。


录屏实操

录屏暂未发布,请耐心等待

发布于:2020-7-17 1楼#

对了 封装程度要迁移其他项目上也能用