如何设计高效的write2Bytes同步API?兼顾性能与调用顺序
优化后的 write2Bytes API 设计方案
针对既要保证写入顺序、避免异步Promise性能损耗,又要正确处理socket异步写入的需求,我们可以通过内部维护写入队列与状态标记的方式实现:大部分场景下同步写入内存,仅当需要刷写socket时触发异步逻辑,且自动保证后续写入请求的顺序执行。
核心设计要点
- 维护固定大小的缓存buf,同步写入数据直到buf填满
- 当buf填满时,将有效数据刷写到socket,同时暂存后续的写入请求
- 用状态标记避免并发刷写socket,socket写入完成后自动处理暂存的请求
- 调用者可保持同步调用习惯,无需额外await,仅在需要等待所有数据发送完成时调用辅助方法
实现代码
const buf = Buffer.alloc(1024); let offset = 0; let isFlushing = false; const pendingWrites = []; function write2Bytes(val) { // 尝试直接写入当前缓存 if (offset + 2 <= buf.length) { buf[offset++] = val; buf[offset++] = val + 1; } else { // 缓存已满,将当前数据加入待处理队列 pendingWrites.push(val); // 如果没有正在进行的socket刷写,触发一次刷写 if (!isFlushing) { flush(); } } } // 内部方法:将当前缓存的有效数据刷写到socket function flush() { isFlushing = true; // 仅发送缓存中的有效数据(前offset字节),避免发送空数据 socket.write(buf.slice(0, offset), (err) => { if (err) { console.error("Socket写入失败:", err); // 可根据业务需求添加错误重试或降级逻辑 } // 重置缓存偏移量 offset = 0; isFlushing = false; // 处理待处理队列中的剩余数据 processPendingQueue(); }); } // 内部方法:批量处理待写入队列中的数据 function processPendingQueue() { if (pendingWrites.length === 0 || isFlushing) return; // 尽可能将队列中的数据写入缓存 while (pendingWrites.length > 0 && offset + 2 <= buf.length) { const val = pendingWrites.shift(); buf[offset++] = val; buf[offset++] = val + 1; } // 如果缓存再次填满,继续触发刷写 if (offset === buf.length) { flush(); } } // 可选辅助方法:等待所有缓存数据与待处理队列完成发送 function flushAll() { return new Promise((resolve, reject) => { // 无待处理任务时直接resolve if (!isFlushing && pendingWrites.length === 0 && offset === 0) { resolve(); return; } // 如果缓存中有未发送的数据,先触发刷写 if (offset > 0 && !isFlushing) { flush(); } // 轮询检查是否所有任务完成 const checkCompletion = () => { if (!isFlushing && pendingWrites.length === 0 && offset === 0) { resolve(); } else { setImmediate(checkCompletion); } }; checkCompletion(); }); } // 使用示例 write2Bytes(4); write2Bytes(4); // 若需要等待所有数据发送完成,可调用: // await flushAll();
方案优势
- 性能最优:同步写入路径无Promise创建、无异步调度开销,仅在刷写socket时触发异步逻辑
- 顺序保证:内部自动维护写入顺序,调用者无需手动处理异步等待,避免数据覆盖或乱序
- 兼容性强:调用方式与原同步函数一致,无需修改原有业务代码结构
- 灵活性高:提供
flushAll方法,满足需要等待所有数据发送完成的场景
内容的提问来源于stack exchange,提问作者Pavan Kumar
相关产品推荐
相关产品推荐

