全局变量的危险.md

全局变量的危险

​ 对于新手来说,有一点非常讽刺,那就是当我们这些新手认为某些特性很有用而大量使用时,往往那些经验丰富的程序员都会非常谨慎的对待。像是全局变量,很多新手都非常喜欢(我倒是谈不上喜欢或讨厌),因为它的作用域是整个源文件,整个程序的各个部分都可以使用,于是我们就不需要将它们作为参数传递给函数。但是,就是因为程序中的各个部分都可以随意使用它,才使得全局变量存在很大的风险:假设这种情况,当我们的程序因为一个变量的错误赋值而出现问题时,如果是某个函数的局部变量,我们只需要在该函数的可见域里面找问题,但是如果是全局变量呢?那么问题就可能出现在整个程序中任何地方了。所以,最好的做法就是避免使用全局变量,如果我们的程序中有一个以上的全局变量,我们就需要认真斟酌,其中是否有些根本就不需要声明为全局变量呢。
这里又有一个新的疑问,好吧,我可以不使用全局变量,但是这样全局变量还有意义吗!!当然有,而且意义很大。全局变量最根本作用就是作为模块函数调用间的内部状态。什么是内部状态呢?举个例子,如果现在我正在写一个图形库,里面每条线都是从上一条线的结束处开始,那么我们就必须记录这个结束处作为内部状态的一部分。可以这样认为,内部状态就是各个函数调用间的通信,当这个状态因为某个函数而改变时,会使另一个函数调用开始发挥作用。局部变量根本不能作为内部状态,因为它的作用域只是它所声明的函数,函数一旦结束,它所存储的值也就丢失。但是,这时使用全局变量依然并不代表我们的程序是安全的,全局变量的危险依然存在。所以,这时我们就要使用static来修饰全局变量,使它的链接性变为内部。这种情况对于多模块的程序来说尤其重要,因为全局变量对于这个文件都是可见的,所以如果没有static,那么任何模块都可以使用,而且不能声明一个重名的变量,但是我们知道,实际开发中,是不同人进行不同模块的开发的,彼此间对于变量名的使用是不知道的,所以名称冲突是随时会发生的,尤其是对于同一个问题的开发。使用static,就可以避免这种冲突,因为static全局变量只对于所声明的模块是可见的,只可以在所声明的模块中使用,其他模块无法使用,所以其他模块是可以声明一个重名的变量的。虽然static在很多程序语言中的意义是说明对象是如何存储的,但是它的使用意义却更接近于private。
所以,如果我们使用一个全局变量,请在前面加上static,这样就可以避免一些我们不知道的错误。

<template> <div class="main"> <div> <div class="trend-content"> <div class="chart-placeholder"> <!-- 加载中提示 --> <div v-if="isLoading" class="loading"> <p>正在加载中...</p> </div> <!-- 后端返回内容渲染(支持Markdown格式) --> <div v-else class="strategy-content" v-html="talkStrategy"></div> </div> </div> </div> </div> </template> <script lang='ts'> import { reactive, toRefs, onMounted, nextTick } from 'vue' // import { useRoute } from 'vue-router' import { marked } from 'marked' // 导入WebSocket工具函数 import { getWsUrl } from './utils/webscoket'; // 定义类型接口,规范数据结构 interface WsResponse { answer?: string; is_stop?: boolean; [key: string]: any; } export default { name: 'TrendDrawerPage', setup() { const data = reactive({ currentRow: null as CurrentRow | null, socket: null as WebSocket | null, wsMessage: null as string | null, isLoading: false, talkStrategy: "", }); // Markdown格式化函数 const formatMarkdown = (content: string): string => { if (!content) return "<p>暂无分析结果</p>"; // 使用marked库解析Markdown(更规范的处理方式) // 自定义marked渲染器来优化样式 const renderer = new marked.Renderer(); // 自定义标题渲染 - 修复方法签名 renderer.heading = ({ text, depth }: { text: string; depth: number }) => { const headingClass = `md-heading md-heading-${depth}`; return `<h${depth} class="${headingClass}">${text}</h${depth}>`; }; // 自定义段落渲染 renderer.paragraph = (text) => { return `<p class="md-paragraph">${text}</p>`; }; // 自定义列表渲染 renderer.list = (body, ordered, start) => { const tag = ordered ? "ol" : "ul"; return `<${tag} class="md-list"${ start ? ` start="${start}"` : "" }>${body}</${tag}>`; }; renderer.listitem = (text) => { return `<li class="md-list-item">${text}</li>`; }; // 自定义分隔线 renderer.hr = () => '<hr class="md-divider">'; // 配置marked选项 marked.setOptions({ renderer: renderer, breaks: true, gfm: true, }); // 解析Markdown return marked(content); }; // 发送分析请求 const sendAnalysisRequest = () => { if (!data.socket || data.socket.readyState !== WebSocket.OPEN) { console.error("WebSocket 未连接"); return; } const requestData = { task_type: data.currentRow?.type, person_name: data.currentRow?.intervieweeName, talk_reason: data.currentRow?.thyy, timestamp: data.currentRow?.startTime, context: "", question: "", }; try { const jsonStr = JSON.stringify(requestData); data.socket.send(jsonStr); } catch (error) { console.error("JSON序列化失败:", error); data.talkStrategy = `<p>数据发送失败:${(error as Error).message}</p>`; data.isLoading = false; } }; // 抽屉关闭回调 const onDrawerClose = (done: () => void) => { // 关闭WebSocket连接 if (data.socket) { data.socket.close(1000, "用户关闭抽屉"); data.socket = null; } done(); // 确认关闭抽屉 }; // 初始化趋势分析 const trend = async () => { data.currentRow = { id: -1, type: '历史趋势', intervieweeName: '测试51号', thyy: '耳目谈话', startTime: '1751253194000', }; data.isLoading = true; data.talkStrategy = ""; // 关闭现有连接 if (data.socket) { data.socket.close(); data.socket = null; } // 等待DOM更新 await nextTick(); if (!data.currentRow?.id) { console.error("缺少任务ID"); data.isLoading = false; data.talkStrategy = "<p>数据错误:缺少任务ID</p>"; return; } // 构建WebSocket URL(结合环境变) let wsUrl = ''; if (import.meta.env.VITE_APP_ENV === 'development') { // 开发环境使用代理路径 wsUrl = `/tendency/ws/ws/talkAnalysis/${data.currentRow.id}`; // wsUrl = `ws://192.168.3.148:8000/ws/talkAnalysis/${data.currentRow.id}`; } else { wsUrl = getWsUrl(`/ws/talkAnalysis/${data.currentRow.id}`); } console.log('WebSocket URL:', wsUrl); try { data.socket = new WebSocket(wsUrl); let accumulatedAnswer = ""; data.socket.onopen = () => { console.log("WebSocket连接成功"); sendAnalysisRequest(); }; data.socket.onmessage = (event) => { data.isLoading = false; try { const res: WsResponse = typeof event.data === "string" ? JSON.parse(event.data) : event.data; if (res.answer) { accumulatedAnswer += res.answer; data.talkStrategy = formatMarkdown(accumulatedAnswer); } if (res.is_stop) { data.socket?.close(); data.socket = null; console.log("流式输出结束"); } } catch (error) { console.error("消息解析错误:", error); data.talkStrategy = `<p>数据解析失败:${(error as Error).message}</p>`; } }; data.socket.onerror = (error) => { console.error("WebSocket错误:", error); data.talkStrategy = "<p>连接失败,请重试</p>"; data.isLoading = false; }; data.socket.onclose = (event) => { if (data.isLoading) data.isLoading = false; console.log(`WebSocket关闭:${event.code} - ${event.reason}`); }; } catch (error) { console.error("创建WebSocket失败:", error); data.isLoading = false; data.talkStrategy = `<p>连接创建失败:${(error as Error).message}</p>`; } }; // 组件挂载时初始化 onMounted(() => { // trend(); }); return { ...toRefs(data), onDrawerClose, }; }, }; </script> <style scoped> .trend-content { height: calc(100% - 40px); min-height: 300px; overflow: auto; padding: 10px 0; } .chart-placeholder { padding: 16px; min-height: 200px; } .loading { display: flex; align-items: center; justify-content: center; height: 200px; color: #666; } .strategy-content { line-height: 1.8; color: #333; } .empty提示 { text-align: center; padding: 50px 0; color: #999; } /* Markdown渲染样式 */ .md-heading { margin: 1.2em 0 0.5em; font-weight: 600; } .md-heading-1 { font-size: 1.5em; border-bottom: 1px solid #eee; padding-bottom: 0.3em; } .md-heading-2 { font-size: 1.3em; } .md-heading-3 { font-size: 1.1em; } .md-paragraph { margin: 0.8em 0; } .md-list { margin: 0.8em 0; padding-left: 1.5em; } .md-list-item { margin: 0.3em 0; } .md-divider { margin: 1em 0; border: 0; border-top: 1px solid #eee; } </style>marked没效果 页面没反应 修复一下吧 亲亲
08-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值