当前位置: 首页 > 科技观察

14条ESLint规则,让你的异步代码更优雅

时间:2023-03-14 16:04:52 科技观察

在用JavaScript编写和调试异步代码时,ESlint可以帮助我们及时发现一些错误。即使在项目中没有使用到这些规则,理解它们的含义也会帮助我们更好的理解和编写异步代码。异步代码的ESLint规则以下规则默认随ESLint一起提供,它们可以在.eslintrc配置文件中启用。1.no-async-promise-executor此规则不允许将异步函数传递给新的Promise构造函数。//?newPromise(async(resolve,reject)=>{});//?newPromise((resolve,reject)=>{});虽然将异步函数传递给Promise构造函数在技术上是可以的,但这样做通常是错误的,原因有二:如果异步函数抛出错误,错误将丢失,不会被新构造的Promise拒绝;如果在构造函数内部使用了await,则包装Promise不是必要的,可以将其删除。2.no-await-in-loop这个规则不允许在循环中使用await。当对可迭代对象的每个元素执行操作并等待异步任务时,通常表明该程序没有充分利用JavaScript的事件驱动架构。通过并行执行这些任务,可以大大提高代码的效率。//?for(consturlofurls){constresponse=awaitfetch(url);}//?constresponses=[];for(consturlofurls){constresponse=fetch(url);responses.push(response);}awaitPromise.all(responses);当确实需要按顺序执行任务时,建议使用行内注释禁用此规则://eslint-disable-lineno-await-in-loop。3.no-promise-executor-return该规则不允许在Promise构造函数中返回值。//?newPromise((resolve,reject)=>{returnresult;});//?newPromise((resolve,reject)=>{resolve(result);});Promise构造函数中返回的值不能使用并且不会以任何方式影响Promise。该值应传递给resolve,如果发生错误,则调用reject并返回错误。此规则不会阻止在Promise构造函数的嵌套回调中返回值。始终确保解决或拒绝承诺。4.require-atomic-updates该规则不允许由于使用await或yield而可能导致竞争条件的赋值。看下面的例子,totalPosts的最终值是多少?//?lettotalPosts=0;asyncfunctiongetPosts(userId){constusers=[{id:1,posts:5},{id:2,posts:3}];等待睡眠(Math.random()*1000);returnusers.find((user)=>user.id===userId).posts;}asyncfunctionaddPosts(userId){totalPosts+=awaitgetPosts(userId);}awaitPromise.all([addPosts(1),添加帖子(2)]);console.log('帖子数:',totalPosts);这里的totalPosts不会打印8,而是会打印5和3。问题是读取和更新totalPosts之间存在时间差。这可能会导致竞争条件,这样当在单独的函数调用中更新值时,更新不会反映在当前函数范围内。因此,这两个函数都将它们的结果添加到初始值为0的totalPosts中。为避免这种竞争条件,请确保在更新变量时读取它://?lettotalPosts=0;asyncfunctiongetPosts(userId){constusers=[{id:1,posts:5},{id:2,帖子:3}];等待睡眠(Math.random()*1000);returnusers.find((user)=>user.id===userId).posts;}asyncfunctionaddPosts(userId){constposts=awaitgetPosts(userId);总帖子数+=帖子数;//变量被读取并立即更新}awaitPromise.all([addPosts(1),addPosts(2)]);console.log('Postcount:',totalPosts);5.max-nested-callbacks此规则强制执行回调的最大嵌套深度。换句话说,这条规则可以防止回调地狱。/*eslintmax-nested-callbacks:["error",3]*///?async1((err,result1)=>{async2(result1,(err,result2)=>{async3(result2,(err,result3)=>{async4(result3,(err,result4)=>{console.log(result4);});});});});//constresult1=awaitasyncPromise1();constresult2=等待asyncPromise2(结果1);constresult3=awaitasyncPromise3(result2);constresult4=awaitasyncPromise4(result3);控制台日志(结果4);深度嵌套使代码难以阅读和维护。在编写JavaScript异步代码时,您可以将回调重构为Promises并使用async/await语法。6.no-return-await该规则不允许返回不必要的await。//?async()=>{returnawaitgetUser(userId);}//?async()=>{returngetUser(userId);}等待Promise并立即返回它是不必要的,因为从异步函数返回所有值for被包裹在Promise中。因此,可以直接返回一个Promise。此规则的一个例外是当存在try...catch语句时,删除await关键字将导致无法捕获Promise拒绝。在这种情况下,建议将结果分配给一个变量以明确意图。//