Deepseek返回数据采用new Map方式的好处
文章类型:Vue
发布者:hp
发布时间:2026-07-01
new Map() 用于创建一个键值对集合,它允许任意类型的值作为键或值,且保持插入顺序。与普通对象不同,Map 的键可以是对象、函数甚至 NaN,且天然支持迭代和大小查询,是处理复杂键映射的高效选择
1:map方式
const thinkingTypewriterQueue = new Map<number, string>()
// 操作
thinkingTypewriterQueue.set(messageId, text) // 设置/更新
thinkingTypewriterQueue.get(messageId) // 获取
thinkingTypewriterQueue.delete(messageId) // 删除
thinkingTypewriterQueue.size // 大小
2:对象方式
const thinkingTypewriterQueue = {}
// 操作
thinkingTypewriterQueue[messageId] = text // 设置/更新
thinkingTypewriterQueue[messageId] // 获取
delete thinkingTypewriterQueue[messageId] // 删除
Object.keys(thinkingTypewriterQueue).length // 大小
3:数组方式
const thinkingTypewriterQueue = []
// 操作
thinkingTypewriterQueue.push({id: messageId, text}) // 添加
thinkingTypewriterQueue.find(item => item.id === messageId) // 查找
thinkingTypewriterQueue = thinkingTypewriterQueue.filter(item => item.id !== messageId) // 删除
thinkingTypewriterQueue.length 1: 性能优势
操作 Map Object Array
查找 O(1) O(1) O(n)
插入 O(1) O(1) O(1)
删除 O(1) O(1) O(n)
遍历 O(n) O(n) O(n)
2: Key 类型安全
// Map 可以使用任何类型作为 key
const messageId = 1234567890 // number 类型
// Map - 保持 number 类型
thinkingTypewriterQueue.set(messageId, "文本")
thinkingTypewriterQueue.get(messageId) // ✅ 正确查找
// Object - 自动转为 string
const queue = {}
queue[messageId] = "文本" // key 变成 "1234567890" (string)
queue[messageId] // 需要确保类型一致
// 可能导致的问题:
queue[1234567890] === queue["1234567890"] // true,但容易混淆
3:更好的 API
// Map 提供了专门的方法
thinkingTypewriterQueue.has(messageId) // 检查是否存在
thinkingTypewriterQueue.clear() // 清空所有
thinkingTypewriterQueue.size // 获取大小(属性)
thinkingTypewriterQueue.keys() // 获取所有 key
thinkingTypewriterQueue.values() // 获取所有 value
thinkingTypewriterQueue.entries() // 获取所有键值对
// Object 需要借助工具函数
Object.prototype.hasOwnProperty.call(queue, messageId) // 检查存在
Object.keys(queue).length // 获取大小(计算)
4: 遍历更可靠
// Map 的遍历顺序是插入顺序,可预测
for (const [messageId, pendingText] of thinkingTypewriterQueue.entries()) {
// 按照插入顺序遍历
// messageId 是 number 类型
// pendingText 是 string 类型
}
// Object 的遍历顺序不保证(特别是在某些情况下)
for (const key in queue) {
// key 是 string 类型
// 顺序可能不稳定
}
1: 多消息并发打字
// 假设同时有 3 条消息在打字
// 消息 ID: 1001, 1002, 1003
// 使用 Map
const queue = new Map()
queue.set(1001, "消息1的文本...")
queue.set(1002, "消息2的文本...")
queue.set(1003, "消息3的文本...")
// 打字机逐个处理
for (const [messageId, pendingText] of queue.entries()) {
// 快速找到对应的消息对象
const message = messages.value.find(m => m.id === messageId)
// 显示部分文本
message.thinking = (message.thinking || '') + chunk
// 更新队列
if (remaining.length > 0) {
queue.set(messageId, remaining) // O(1) 快速更新
} else {
queue.delete(messageId) // O(1) 快速删除
}
break // 每次只处理一个
}
2: 追加文本
// 后端持续返回增量文本
// 第1次:reasoning = "我正在"
// 第2次:reasoning = "思考"
// 第3次:reasoning = "这个问题"
// 每次收到新文本,需要追加到队列中
const enqueueThinkingTyping = (message: ChatMessage, text: string) => {
// 获取现有文本 - O(1)
const existing = thinkingTypewriterQueue.get(message.id) || ''
// 追加新文本
const newText = existing + text
// 更新队列 - O(1)
thinkingTypewriterQueue.set(message.id, newText)
// 如果用 Array,需要:
// 1. find 查找对象 - O(n)
// 2. 更新对象
// 3. 没有找到则 push - O(1)
}
3: 清理已完成的消息
// 当某条消息的文本显示完成后
const typewriterStep = () => {
for (const [messageId, pendingText] of thinkingTypewriterQueue.entries()) {
if (pendingText.length > 0) {
// ... 处理显示
if (remaining.length === 0) {
// 已完成,删除 - O(1)
thinkingTypewriterQueue.delete(messageId)
}
} else {
// 空文本,删除 - O(1)
thinkingTypewriterQueue.delete(messageId)
}
}
// 如果用 Array,删除需要:
// queue = queue.filter(item => item.id !== messageId) // O(n)
}
1. 类型定义
// 明确类型,提高代码可读性
const typewriterQueue = new Map<number, string>()
// ↑ ↑
// messageId 待显示文本
2. 安全访问
// 使用 || '' 提供默认值
const existing = thinkingTypewriterQueue.get(message.id) || ''
// 或者使用 ?? (nullish coalescing)
const existing = thinkingTypewriterQueue.get(message.id) ?? ''
3. 条件判断
// 检查队列是否为空
if (thinkingTypewriterQueue.size > 0) {
// 有内容,继续打字
}
// 检查某个消息是否在队列中
if (thinkingTypewriterQueue.has(messageId)) {
// 该消息还有待显示内容
}
4. 清理资源
// 清空整个队列
thinkingTypewriterQueue.clear()
typewriterQueue.clear()
// 或者逐个删除
for (const messageId of thinkingTypewriterQueue.keys()) {
thinkingTypewriterQueue.delete(messageId)
}
✅ O(1) 性能 - 增删改查都很快
✅ 类型安全 - key 可以是任意类型(我们用 number)
✅ API 简洁 - 专门的方法,语义清晰
✅ 顺序保证 - 遍历顺序就是插入顺序
✅ 易于管理 - size 属性,clear 方法等
✅ 适合场景 - 需要通过 ID 快速查找和更新
为什么选择 Map?
暂无评论,快来发表第一条评论吧~