如何让表达支持async/等待

  介绍

小编给大家分享一下如何让表达支持async/等待,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

随着节点。js v8的发布,节点。js已原生支持async/等待函数,网框架高雅也随之发布了高雅2正式版,支持async/等待中间件,为处理异步回调带来了极大的方便。

既然高雅2已经支持async/等待中间件了,为什么不直接用高雅,而还要去改造表达让其支持async/等待中间件呢?因为高雅2正式版发布才不久,而很多老项目用的都还是表达,不可能将其推倒用洋槐重写,这样成本太高,但又想用到新语法带来的便利,那就只能对表达进行改造了,而且这种改造必须是对业务无侵入的,不然会带来很多的麻烦。

<强>直接使用异步/等待

让我们先来看下在表达中直接使用异步/等待函数的情况。

const  express =,要求(& # 39;表达# 39;);   const  app =,表达();   {const  promisify },=,要求(& # 39;util # 39;);   {const  readFile },=,要求(& # 39;fs # 39;);   const  readFileAsync =, promisify (readFile);   ,,   app.get (& # 39;/& # 39;,, async  function (申请,,,,下一个){   ,const  data =, await  readFileAsync (& # 39;。/package.json& # 39;);   ,res.send (data.toString ());   });//Error 处理程序   app.use (function (呃,,要求的事情,,,,下一个){   ,console.error(& # 39;错误:& # 39;,,呃);   ,res.status (500) .send (& # 39; Service 错误# 39;);   });   ,,   app.listen (3000, & # 39; 127.0.0.1 # 39;,, function  () {   ,console.log (“Server  running  at  http://$ {this.address () .address }: $ {this.address () .port }/');   });

上面是没有对表达进行改造,直接使用异步/等待函数来处理请求,当请求http://127.0.0.1:3000时,发现请求能正常请求,响应也能正常响应。这样似乎不对表达做任何改造也能直接使用异步/等待函数,但如果async/等待函数里发生了错误能不能被我们的错误处理中间件处理呢?现在我们去读取一个不存在文件,例如将之前读取的包。json换成年龄。json .

app.get (& # 39;/& # 39;,, async  function (申请,,,,下一个){   ,const  data =, await  readFileAsync (& # 39;。/age.json& # 39;);   ,res.send (data.toString ());   });

现在我们去请求http://127.0.0.1:3000时,发现请求迟迟不能响应,最终会超时。而在终端报了如下的错误:

如何让表达支持async/等待

发现错误并没有被错误处理中间件处理,而是抛出了一个unhandledRejection异常,现在如果我们用try/catch来手动捕获错误会是什么情况呢?

app.get (& # 39;/& # 39;,, async  function (申请,,,,下一个){   ,try  {   const 才能;data =, await  readFileAsync (& # 39;。/age.json& # 39;);   res.send才能(datas.toString ());   }大敌;抓(e), {   下才能(e);   ,}   });

发现请求被错误处理中间件处理了,说明我们手动显式的来捕获错误是可以的,但是如果在每个中间件或请求处理函数里面加一个try/catch也太不优雅了,对业务代码有一定的侵入性,代码也显得难看。所以通过直接使用异步/等待函数的实验,我们发现对表达改造的方向就是能够接收async/等待函数里面抛出的错误,又对业务代码没有侵入性。

<强>改造表达

在表达中有两种方式来处理路由和中间件,一种是通过表达创建的应用,直接在应用上添加中间件和处理路由,像下面这样:

const  express =,要求(& # 39;表达# 39;);   const  app =,表达();   ,,   app.use (function (申请,,,,下一个){   接下来,();   });   app.get (& # 39;/& # 39;,, function (申请,,,,下一个){   ,res.send(& # 39;你好,,& # 39;);   });   app.post (& # 39;/& # 39;,, function (申请,,,,下一个){   ,res.send(& # 39;你好,,& # 39;);   });   ,,   app.listen (3000, & # 39; 127.0.0.1 # 39;,, function  () {   ,console.log (“Server  running  at  http://$ {this.address () .address }: $ {this.address () .port }/');   });

另外一种是通过表达的路由器创建的路由实例,直接在路由实例上添加中间件和处理路由,像下面这样:

const  express =,要求(& # 39;表达# 39;);   const  app =,表达();   const  router =, new  express.Router ();   app.use(路由器);   ,,   router.get (& # 39;/& # 39;,, function (申请,,,,下一个){   ,res.send(& # 39;你好,,& # 39;);   });   router.post (& # 39;/& # 39;,, function (申请,,,,下一个){   ,res.send(& # 39;你好,,& # 39;);   });   ,,   app.listen (3000, & # 39; 127.0.0.1 # 39;,, function  () {   ,console.log (“Server  running  at  http://$ {this.address () .address }: $ {this.address () .port }/');   });

如何让表达支持async/等待