优化ES6 Promise调用以提升组织架构图性能的技术问询
重构Promise实现动画与数据请求并行,消除不必要延迟
你的核心问题是原来的代码把动画和数据请求做成了串行执行,浪费了动画播放时的等待时间。我们可以通过并行启动两个异步操作,再用Promise.all()等待两者都完成的方式来优化,完全保留你现有的Promise函数,只调整调用逻辑:
重构后的代码
/* Click happened! */ // 1. 点击后立即发起数据请求,不用等动画结束 const fetchDataPromise = fetch(`api/org/${target.id}/1`) .then(result => result.children); // 提前提取需要的数据,方便后续使用 // 2. 同时启动第一个动画 const shiftRowAnimationPromise = orgWrap.shiftRow({ row: clickY, from: clickX, to: focusX }); // 3. 等待动画完成 AND 数据请求完成,再执行后续操作 Promise.all([shiftRowAnimationPromise, fetchDataPromise]) .then(([_, childrenData]) => { // 先把数据渲染到DOM orgWrap.populateRow({ data: childrenData, row: clickY + 1 }); // 这里可以添加你的最后一个动画逻辑,它会在前面两个操作都完成后才触发 }) .catch(err => { // 可选:统一处理错误,比如动画失败或请求失败的情况 console.error('操作出错:', err); });
关键改动说明
- 并行启动异步操作:原来的代码是等
shiftRow动画结束才开始fetch,现在我们在点击事件触发后,同时启动这两个操作,让动画播放和数据请求同时进行,充分利用等待时间,彻底消除两者之间的延迟。 - 用
Promise.all()做同步等待:这个方法会等待传入的所有Promise都成功resolve后,才会执行后续的回调,完美满足你“最后一个动画需在数据获取完成且第一个动画结束后再执行”的需求。 - 提前处理数据:在
fetch的then里直接提取result.children,这样后续回调可以直接拿到可用的数据,减少嵌套层级。
可选的错误处理优化
如果担心其中一个操作失败影响整体流程,可以给每个Promise单独添加错误捕获,或者在Promise.all后统一处理:
Promise.all([ // 捕获动画失败的情况,不影响数据请求 shiftRowAnimationPromise.catch(err => { console.error('行移动动画失败:', err); return null; }), // 捕获请求失败的情况,不影响动画 fetchDataPromise.catch(err => { console.error('获取组织数据失败:', err); return null; }) ]) .then(([_, childrenData]) => { // 确保数据存在时再渲染 if (childrenData) { orgWrap.populateRow({ data: childrenData, row: clickY + 1 }); } });
这样即使其中一个操作失败,另一个成功的情况下,业务逻辑依然可以正常推进(具体错误处理逻辑可以根据你的业务需求调整)。
内容的提问来源于stack exchange,提问作者Audun Olsen
相关产品推荐
相关产品推荐

