setTimeout怎么用【详细讲解】

本文详细介绍了JavaScript的setTimeout函数,包括其基本用法、箭头函数形式,以及它并不保证在指定时间立即执行,而是将函数加入异步任务队列,等待执行的特点。

setTimeout 是 JavaScript 提供的一个函数,用于在指定的时间延迟后执行一段代码(函数)。它的基本用法如下:

setTimeout(function, delay);
  • function: 要执行的函数。
  • delay: 延迟的毫秒数。

示例:

console.log("Start");
setTimeout(function() {
  console.log("Delayed log after 2000ms");
}, 2000);
console.log("End");

在这个示例中,"Start""End" 会立即被打印,而 "Delayed log after 2000ms" 将会在 2000 毫秒(2秒)后被打印出来。

你也可以使用箭头函数来实现同样的效果:

console.log("Start");
setTimeout(() => {
  console.log("Delayed log after 2000ms");
}, 2000);
console.log("End");

需要注意的是,setTimeout 不保证在指定的毫秒数之后立即执行,它只是将函数放入异步任务队列中,并在队列中的等待时间过后执行。如果队列中有其他任务需要执行,那么可能会稍微延迟执行。

WebSocket 是一种在单个 TCP 连接上进行**全双工通信**的网络协议,它允许客户端和服务器之间**实时、双向地交换数据**,而无需像传统 HTTP 那样反复建立连接。它是现代 Web 实时应用(如聊天室、在线协作、股票行情推送等)的核心技术之一。 --- ## 一、为什么需要 WebSocket? ### 🔹 传统 HTTP 的局限性 HTTP 是**请求-响应模式**的协议: ```http 客户端:GET /data HTTP/1.1 服务器:200 OK + 数据 ``` - 每次通信都必须由客户端发起 - 服务器无法主动向客户端发送数据 - 如果想“实时”获取更新,只能靠轮询(Polling) ### ❌ 轮询的问题: | 类型 | 缺点 | |------|------| | 短轮询(Short Polling) | 频繁请求,浪费带宽与资源 | | 长轮询(Long Polling) | 延迟较高,连接占用久 | > 🚫 所以我们需要一种机制:**让服务器能主动推消息给客户端** --- ## ✅ 解决方案:WebSocket 协议登场! WebSocket 在 **一次 HTTP 握手后升级为持久连接**,之后双方可以随时互发消息,实现真正的“即时通讯”。 --- ## 二、WebSocket 的工作原理 ### 1. 连接建立:通过 HTTP 升级(Upgrade) WebSocket 使用 `ws://` 或加密的 `wss://` 协议。 #### 客户端发起握手请求(HTTP Upgrade) ```http GET /chat HTTP/1.1 Host: example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 ``` #### 服务器返回成功响应 ```http HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= ``` > ✅ 此时,底层 TCP 连接保持打开,后续通信不再使用 HTTP,而是使用 WebSocket 二进制帧格式。 --- ### 2. 数据传输:全双工通信 一旦连接建立,客户端和服务器都可以随时发送数据: ```text Client ──────→ Server (任意时刻) Client ←────── Server (任意时刻) ``` 数据以“帧”(frame)的形式传输,支持: - 文本帧(UTF-8 字符串) - 二进制帧(图片、音频、自定义协议等) - 控制帧(ping/pong 用于心跳检测) --- ### 3. 连接关闭 任何一方可以发送关闭帧(Close Frame),对方回应后断开连接。 ```text A: Close B: Close Ack → TCP 连接关闭 ``` --- ## 三、WebSocket API 使用示例(JavaScript) ### 前端代码(浏览器中) ```javascript // 创建 WebSocket 连接 const socket = new WebSocket('ws://localhost:8080'); // 连接成功时 socket.onopen = function(event) { console.log('连接已建立'); socket.send('你好,服务器!'); }; // 收到服务器消息时 socket.onmessage = function(event) { console.log('收到消息:', event.data); }; // 发生错误时 socket.onerror = function(error) { console.error('发生错误:', error); }; // 连接关闭时 socket.onclose = function(event) { console.log('连接已关闭', event.code, event.reason); }; // 主动关闭连接 // socket.close(); ``` --- ### 后端示例(Node.js + ws 库) ```bash npm install ws ``` ```javascript const WebSocket = require('ws'); const server = new WebSocket.Server({ port: 8080 }); server.on('connection', (socket) => { console.log('新客户端连接'); // 接收消息 socket.on('message', (data) => { console.log('收到:', data.toString()); // 回复所有人(广播) server.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(`广播: ${data}`); } }); }); // 连接关闭 socket.on('close', () => { console.log('客户端断开'); }); }); ``` --- ## 四、WebSocket vs 其他实时技术对比 | 技术 | 通信方向 | 实时性 | 兼容性 | 适用场景 | |------|----------|--------|--------|-----------| | **WebSocket** | 双向 | ⭐⭐⭐⭐⭐ | 现代浏览器 | 聊天、游戏、协同编辑 | | 长轮询(Long Polling) | 单向(伪实时) | ⭐⭐☆ | 极好 | 老旧系统兼容 | | SSE(Server-Sent Events) | 服务器 → 客户端 | ⭐⭐⭐⭐ | 较好 | 行情推送、通知 | | HTTP/2 Server Push | 服务器 → 客户端 | ⭐⭐⭐ | 依赖 HTTPS | 页面资源预推 | > ✅ WebSocket 是目前唯一支持**真正双向实时通信**的标准协议。 --- ## 五、WebSocket 的关键特性 | 特性 | 说明 | |------|------| | **持久连接** | 一个连接可维持数小时甚至更久 | | **低延迟** | 消息直达,无频繁握手开销 | | **高效传输** | 帧头部仅 2~14 字节,远小于 HTTP 头 | | **跨域支持** | 可配置 CORS 和 token 认证 | | **心跳机制** | 通过 ping/pong 帧检测连接是否存活 | | **子协议支持** | 可协商使用自定义协议(如 `chat`, `json.rpc`) | ```javascript // 使用子协议 const socket = new WebSocket('ws://host/socket', ['chat', 'v1']); ``` --- ## 六、实际应用场景 | 场景 | 说明 | |------|------| | 💬 在线聊天室 | 用户发送消息,服务器广播给所有人 | | 🎮 多人在线游戏 | 实时同步玩家位置、动作 | | 📈 股票/币价行情 | 服务器持续推送最新价格 | | 📝 协同编辑文档 | 多人同时编辑,实时同步变更 | | 🔔 实时通知系统 | 新消息提醒、订单状态更新 | | 🖥️ 远程控制台 | Web SSH 终端(如 GitHub Codespaces) | --- ## 七、安全性考虑 虽然强大,但 WebSocket 也带来安全风险: | 风险 | 防范措施 | |------|----------| | **未授权访问** | 握手阶段验证 Cookie/token | | **跨站 WebSocket 劫持(CSWSH)** | 检查 Origin 头或使用 CSRF Token | | **消息注入** | 对接收的消息做输入校验与转义 | | **DDoS 攻击** | 限制连接数、频率控制 | | **明文传输** | 使用 `wss://`(基于 TLS 加密) | > ✅ 最佳实践:始终使用 `wss://` 替代 `ws://` --- ## 八、常见问题与解决方案 | 问题 | 解决方案 | |------|----------| | 连接中断怎么办? | 实现自动重连机制(指数退避) | | 如何保持连接活跃? | 设置心跳(每30秒ping一次) | | 如何处理大量并发连接? | 使用事件驱动架构(如 Node.js、Netty) | | 如何实现消息可靠传递? | 添加 ACK 机制 + 消息持久化 | | 如何支持离线消息? | 结合数据库记录未送达消息 | ```javascript // 示例:带重连机制的 WebSocket 封装 class ReconnectingWebSocket { constructor(url) { this.url = url; this.connect(); } connect() { const socket = new WebSocket(this.url); socket.onopen = () => console.log("连接成功"); socket.onclose = () => setTimeout(() => this.connect(), 3000); // 3秒后重连 socket.onmessage = (e) => console.log(e.data); this.socket = socket; } send(data) { this.socket.send(data); } } ``` --- ## 九、WebSocket 在微服务与移动端中的应用 - **微服务间通信**:替代部分 RPC,用于事件通知 - **移动端推送**:配合 APNs/FCM,也可直接长连接保活 - **IoT 设备通信**:传感器数据上传与指令下发 --- ## 总结:WebSocket 的核心价值 | 维度 | 说明 | |------|------| | 🎯 目标 | 实现 Web 端真正的实时双向通信 | | 🔗 基础 | 基于 TCP,通过 HTTP 协议升级建立 | | ⚡ 优势 | 低延迟、高并发、节省资源 | | 🛠️ 工具链成熟 | 浏览器原生支持、各类语言均有库 | | 🌐 标准化 | W3C 和 IETF 标准(RFC 6455) | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值