不愧是前端老油条,分分钟看出我方案的bug

2023-10-30 16:20

本文主要是介绍不愧是前端老油条,分分钟看出我方案的bug,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击上方关注 前端技术江湖,一起学习,天天进步

国庆前刚开发完一个小需求,常规性的做了一次code review,不过这次review有所不同,我们组前端老油条竟然参会了,平时发会邀都不来的。

不过不愧是老油条,竟然分分中发现了问题,老油条的地位又在我们小前端的心里巩固了一下。

和往常一样,review前先过一遍技术方案,一让大家快速的了解需求,二来分析下技术方案是否存在问题,是否合理,一般情况下,技术方案没问题,后面的代码review感觉就没啥必要了,因为很少有人听。

e8f2594a8bcce21068b8eae254560ff6.png

就在刚要讲完技术方案,要进入review代码阶段,老油条提出了问题,我心想这么简单的需求会有啥问题?

到这里我不得不把需求搬出来,让各位看官瞅瞅,一起来看是否存在这样的问题,换作是你,你会怎样处理。

需求超简单,上截图

64c189dfc1b97c3bd38a25b7c0187591.png
image.png

上面是一个分类数据展示页面,左侧是一级分类,右侧二级分类和三级分类,然后下面是推荐的商品列表。

就这样一个页面会有什么问题呢?撑死2个接口,一个分类接口,一个商品推荐接口。

问题在于交互上,左边的一级分类可以随意切换,如果用户不讲武德,不等右边的数据渲染完就切换了,那会给用户带来什么体验呢?

会导致渲染结果混乱,旧数据渲染在了新的分类里。

解决方案

其实很简单,切换分类时,取消上一个请求。

怎样实现取消请求呢?

下面咱们就来总结性的看下如何取消一个请求,看哪个方式更简单易用。

思路:项目中的网络请求模块一般都是基于promise进行封装,返回一个promise对象,其实只要把 promise 取消掉就可以,其实并不是真正的取消网络请求,而是丢弃返回的数据。

方法1 - 借助reject方法

fe都知道一个promise对象状态的改变是通过resolve和reject来执行的。那是不是可以借助reject方法来模拟呢?

//返回一个promise和abort方法
function getPromise() {let _res, _rej;const promise = new Promise((resolve, reject) => {_res = resolve;_rej = reject;setTimeout(() => {resolve('123')}, 5000);});return {promise,abort: () => {_rej({name: "abort",message: "the promise is aborted",aborted: true,});}};
}const { promise, abort } = getPromise();
promise.then(console.log).catch(e => {console.log(e);
});abort();

上面的方法可以正常执行,但是不够通用,可以将Promise构造函数内的逻辑提取出来,作为一个回调传进去。

改造后

function getPromise(cb) {let _res, _rej;const promise = new Promise((res, rej) => {_res = res;_rej = rej;cb && cb(res,rej);});return {promise,abort: () => {_rej({name: "abort",message: "the promise is aborted",aborted: true,});}};
}//主逻辑提取出来
function runCb(resolve,reject){setTimeout(()=>{resolve('1111')},3000)
}const { promise, abort } = getPromise(runCb);
promise.then(console.log).catch(e => {console.log(e);
});

方法2  - 借助 Promise.race()

简单复习下race方法的作用,当有若干个promise, p1, p2, p3…在调用, let p = Promise.race([p1, p2, p3,…])的时候,返回的p也是一个promise。那么p什么时候会被resolve或者被reject呢?

看race单词的意思就知道它是竞速或赛跑的意思,所以p1, p2, p3 … 最先一个被resolve或者被reject的结果就是p的resolve或者reject的结果。所以后续的promise的resolve和reject都不会再被执行了。

代码很简单,但足够短小精悍。

//传入一个正在执行的promise
function getPromiseWithAbort(p){let obj = {};//内部定一个新的promise,用来终止执行let p1 = new Promise(function(resolve, reject){obj.abort = reject;});obj.promise = Promise.race([p, p1]);return obj;
}

调用~

var promise  = new Promise((resolve)=>{setTimeout(()=>{resolve('123')},3000)
})var obj = getPromiseWithAbort(promise)obj.promise.then(res=>{console.log(res)})//如果要取消
obj.abort('取消执行')
6b6bacd9bfe523dd404c836f346c9c85.png
image.png

借助race方法明显的更简洁,更易用。

最后

取消promise执行和取消请求是一样的,并不是真的终止了请求的执行,而是丢弃了数据,对结果不再处理。另外fetch api虽然增加了新的标准实现(AbortSignal),但仍然存在兼容问题,而且只能在浏览器中使用。那么非浏览器的环境中呢?比如RN?小程序?所以如果想要达到一种通用的方式,那么本文的reject promise的方式应该是个不错的方式。

此时我看着11点方向的前端老油条,肃然起敬,摆正自己的态度,多向前辈学习,做了这么多年的业务还能保持这样的敏锐度。

拿起手机疯狂的自测起自己的需求,忽然发现了一个性能问题,频繁切换竟然会卡。

为啥卡?怎么解决?

e6422a20fa8e9f79cb46c9587f474e33.png

欢迎留言讨论。

The End

欢迎自荐投稿到《前端技术江湖》,如果你觉得这篇内容对你挺有启发,记得点个 「在看」

点个『在看』支持下 294c7a00b512a3e62579beafaff9e161.gif

这篇关于不愧是前端老油条,分分钟看出我方案的bug的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/309135

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Vue3项目开发——新闻发布管理系统(六)

文章目录 八、首页设计开发1、页面设计2、登录访问拦截实现3、用户基本信息显示①封装用户基本信息获取接口②用户基本信息存储③用户基本信息调用④用户基本信息动态渲染 4、退出功能实现①注册点击事件②添加退出功能③数据清理 5、代码下载 八、首页设计开发 登录成功后,系统就进入了首页。接下来,也就进行首页的开发了。 1、页面设计 系统页面主要分为三部分,左侧为系统的菜单栏,右侧

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.