,我在做codereview的时候发现有同事用trycatch包裹了一堆异步代码,所以个人觉得很奇怪。catchonly不应该有问题吗?代码?有同事告诉我,如果trycatch太细了,会出现内外作用域不一致的情况,需要提前声明变量。letres:Data[]=[];try{res=awaitfetchData();}catch(err){//错误操作或终止//return}//继续执行正常逻辑的确,一方面,开发人员Scope不应该包装非异常代码。另一方面,提前声明变量会使代码不连贯,打断思路。一种方法是直接使用原生Promies而不是异步。fetchData().then((res)=>{}).catch((err)=>{});当然,单个异步请求是没有问题的,如果是有依赖的异步请求。虽然Promise中可以返回另一个Promise请求,但是这种方式只能有一个catch。fetchData().then((res)=>{//业务处理returnfetchData2(res);}).then((res)=>{//业务处理}).catch((err)=>{//我们只能做一般的错误处理});如果我们需要多次catch处理,就需要这样写。fetchData().then((res)=>{//业务处理returnfetchData2(res);}).catch((err)=>{//错误处理并返回nullreturnnull;}).then((res)=>{if(res===null){return;}//业务处理}).catch((err)=>{//错误处理});这时候开发者还要考虑fetchData2是否会返回null的问题。所以我个人开始寻找一些方法来帮助我们解决这个问题。await-to-jsawait-to-js是一个帮助开发者处理异步错误的库。我们先来看看这个库是如何解决我们的问题的。importtofrom"await-to-js";const[fetch1Err,fetch1Result]=awaitto(fetchData());if(fetch1Err){//错误操作或终止//return}const[fetch2Err,fetch1Result]=awaitto(fetchData2(fetch1Result));if(fetch2Err){//错误操作或终止//return}源码很简单。导出函数到(promise,errorExt,){returnpromise.then((data)=>[null,data]).catch((err)=>{if(errorExt){constparsedError=Object.assign({},err,errorExt);return[parsedError,undefined];}return[err,undefined];});}使用try-run-js看到await-to-js使用errors是正常流程的一部分,所以我个人想想trycatch能不能解决一些异步代码问题?我立即想到需要获取DOM节点。现有的框架都采用了数据驱动的思想,但是DOM什么时候渲染出来是未知的,所以个人认为之前的代码,Vue需要获取ref并进行回调处理。functionresolveRef(refName,callback,ti??me:number=1){//超过10次递归中断if(time>10)thrownewError(`cannotfindref:${refName}`);//constself=this;//获取ref节点constref=this.$refs[refName];如果(参考){回调(参考);}else{//下一次如果没有节点this.$nextTick(()=>{resolveRef.call(self,refName,callback,ti??me+1);});}}当然上面的代码确实可以解决这类问题,我们在处理这类问题的时候可以替换ref和nextTick的代码。于是在await-to-js的逻辑下,我自己开发了try-run-js这个库。让我们看看这个库是如何使用的。importtryRunfrom"try-run-js";tryRun(()=>{//尽量直接使用正常逻辑代码//不要加?。//代码不会出错,不会重试this.$refs.navTree.setCurrentKey("xxx");},{//重试次数retryTime:10,//下一次操作超时前的延迟时间:()=>{newPromise((resolve)=>{this.$nextTick(解决);});},});我们还可以获得错误数据和结果。从“try-run-js”导入tryRun;constgetDomStyle=async()=>{//一步获取const{error:domErr,result:domStyle}=awaittryRun(()=>{//返回dom节点样式,不管是否有ppt//不加吗。//代码不会出错返回undefinedreturndocument.getElementById("domId").style;},{//重试次数retryTime:3,//ReturnFornumbers,functionwillusesetTimeout//参数为当前重试次数,第一次重试100ms,第二次200timeout:(time)=>time*100,//也可以不传直接返回次数默认是333//超时:333});如果(domErr){返回{};}返回domStyle;};当然,这个库也支持返回元组和await-to-jsPromise错误处理的功能。从“try-run-js”导入{tryRunForTuple};const[error,result]=awaittryRunForTuple(fetchData());try-run-js项目演进try-run-js的核心在于try-catch的处理,下面是关于try-run-js的编写思路。希望能对大家有所帮助。支持await-to-jsconstisObject=(val:any):valisObject=>val!==null&&(typeofval==="object"||typeofval==="function");constisPromise=
