专门做化妆品平台的网站有哪些深圳网络科技有限公司有哪些

diannao/2026/1/26 11:06:37/文章来源:
专门做化妆品平台的网站有哪些,深圳网络科技有限公司有哪些,南京seo推广优化,wordpress模板克隆前言用了那么多年的express.js#xff0c;终于有时间来深入学习express#xff0c;然后顺便再和koa2的实现方式对比一下。老实说#xff0c;还没看express.js源码之前#xff0c;一直觉得express.js还是很不错的#xff0c;无论从api设计#xff0c;还是使用上都是可以的…前言用了那么多年的express.js终于有时间来深入学习express然后顺便再和koa2的实现方式对比一下。老实说还没看express.js源码之前一直觉得express.js还是很不错的无论从api设计还是使用上都是可以的。但是这次阅读完express代码之后我可能改变想法了。虽然express.js有着精妙的中间件设计但是以当前js标准来说这种精妙的设计在现在可以说是太复杂。里面的层层回调和递归不花一定的时间还真的很难读懂。而koa2的代码呢简直可以用四个字评论精简彪悍仅仅几个文件用上最新的js标准就很好实现了中间件代码读起来一目了然。老规矩读懂这篇文章我们依然有一个简单的demo来演示 express-vs-koa1、express用法和koa用法简单展示如果你使用express.js启动一个简单的服务器那么基本写法应该是这样const express require(express)const app express() const router express.Router()app.use(async (req, res, next) {console.log(I am the first middleware)next()console.log(first middleware end calling) }) app.use((req, res, next) {console.log(I am the second middleware)next()console.log(second middleware end calling) })router.get(/api/test1, async(req, res, next) {console.log(I am the router middleware /api/test1)res.status(200).send(hello) })router.get(/api/testerror, (req, res, next) {console.log(I am the router middleware /api/testerror)throw new Error(I am error.) })app.use(/, router)app.use(async(err, req, res, next) {if (err) {console.log(last middleware catch error, err)res.status(500).send(server Error)return}console.log(I am the last middleware)next()console.log(last middleware end calling) })app.listen(3000) console.log(server listening at port 3000) 换算成等价的koa2那么用法是这样的const koa require(koa) const Router require(koa-router)const app new koa() const router Router()app.use(async(ctx, next) {console.log(I am the first middleware)await next()console.log(first middleware end calling) })app.use(async (ctx, next) {console.log(I am the second middleware)await next()console.log(second middleware end calling) })router.get(/api/test1, async(ctx, next) {console.log(I am the router middleware /api/test1)ctx.body hello })router.get(/api/testerror, async(ctx, next) {throw new Error(I am error.) })app.use(router.routes())app.listen(3000) console.log(server listening at port 3000) 如果你还感兴趣原生nodejs启动服务器是怎么使用的可以参考demo中的这个文件node.js于是二者的使用区别通过表格展示如下(知乎不支持markdown也是醉了~表格只能截图了~)上表展示了二者的使用区别从初始化就看出koa语法都是用的新标准。在挂载路由中间件上也有一定的差异性这是因为二者内部实现机制的不同。其他都是大同小异的了。那么接下去我们的重点便是放在二者的中间件的实现上。2、express.js中间件实现原理我们先来看一个demo展示了express.js的中间件在处理某些问题上的弱势。demo代码如下const express require(express)const app express()const sleep (mseconds) new Promise((resolve) setTimeout(() {console.log(sleep timeout...)resolve() }, mseconds))app.use(async (req, res, next) {console.log(I am the first middleware)const startTime Date.now()console.log( start ${req.method} ${req.url}, { query: req.query, body: req.body });next()const cost Date.now() - startTimeconsole.log( end ${req.method} ${req.url} ${res.statusCode} - ${cost} ms) }) app.use((req, res, next) {console.log(I am the second middleware)next()console.log(second middleware end calling) })app.get(/api/test1, async(req, res, next) {console.log(I am the router middleware /api/test1)await sleep(2000)res.status(200).send(hello) })app.use(async(err, req, res, next) {if (err) {console.log(last middleware catch error, err)res.status(500).send(server Error)return}console.log(I am the last middleware)await sleep(2000)next()console.log(last middleware end calling) })app.listen(3000) console.log(server listening at port 3000) 该demo中当请求/api/test1的时候打印结果是什么呢I am the first middlewarestart GET /api/test1 I am the second middleware I am the router middleware /api/test1 second middleware end callingend GET /api/test1 200 - 3 ms sleep timeout...如果你清楚这个打印结果的原因想必对express.js的中间件实现有一定的了解。我们先看看第一节demo的打印结果是I am the first middleware I am the second middleware I am the router middleware /api/test1 second middleware end calling first middleware end calling这个打印符合大家的期望但是为什么刚才的demo打印的结果就不符合期望了呢二者唯一的区别就是第二个demo加了异步处理。有了异步处理整个过程就乱掉了。因为我们期望的执行流程是这样的I am the first middlewarestart GET /api/test1 I am the second middleware I am the router middleware /api/test1 sleep timeout... second middleware end callingend GET /api/test1 200 - 3 ms那么是什么导致这样的结果呢我们在接下去的分析中可以得到答案。2.1、express挂载中间件的方式要理解其实现我们得先知道express.js到底有多少种方式可以挂载中间件进去熟悉express.js的童鞋知道吗知道的童鞋可以心里默默列举一下。目前可以挂载中间件进去的有(HTTP Method指代那些http请求方法诸如Get/Post/Put等等)app.useapp.[HTTP Method]app.allapp.paramrouter.allrouter.userouter.paramrouter.[HTTP Method]2.2、express中间件初始化express代码中依赖于几个变量(实例)app、router、layer、route这几个实例之间的关系决定了中间件初始化后形成一个数据模型画了下面一张图片来展示图中存在两块Layer实例挂载的地方也不一样以express.js为例子我们通过调试找到更加形象的例子结合二者我们来聊聊express中间件初始化。为了方便我们把上图1叫做初始化模型图上图2叫做初始化实例图看上面两张图我们抛出下面几个问题搞懂问题便是搞懂了初始化。初始化模型图Layer实例为什么分两种初始化模型图Layer实例中route字段什么时候会存在初始化实例图中挂载的中间件为什么有7个初始化实例图中圈2和圈3的route字段不一样而且name也不一样为什么初始化实例图中的圈4里也有Layer实例这个时候的Layer实例和上面的Layer实例不一样吗首先我们先输出这样的一个概念Layer实例是path和handle互相映射的实体每一个Layer便是一个中间件。这样的话我们的中间件中就有可能嵌套中间件那么对待这种情形express就在Layer中做手脚。我们分两种情况挂载中间件使用app.use、router.use来挂载的app.use经过一系列处理之后最终也是调用router.use的使用app.all、app.[Http Method]、app.route、router.all、router.[Http Method]、router.route来挂载的app.all、app.[Http Method]、app.route、router.all、router.[Http Method]经过一系列处理之后最终也是调用router.route的因此我们把焦点聚焦在router.use和router.route这两个方法。2.2.1、router.use该方法的最核心一段代码是for (var i 0; i callbacks.length; i) {var fn callbacks[i];if (typeof fn ! function) {throw new TypeError(Router.use() requires a middleware function but got a gettype(fn))}// add the middlewaredebug(use %o %s, path, fn.name || anonymous)var layer new Layer(path, {sensitive: this.caseSensitive,strict: false,end: false}, fn);// 注意这个route字段设置为undefinedlayer.route undefined;this.stack.push(layer); } 此时生成的Layer实例对应的便是初始化模型图1指示的多个Layer实例此时以express.js为例子我们看初始化实例图圈1的所有Layer实例会发现除了我们自定义的中间件(共5个)还有两个系统自带的看初始化实例图的Layer的名字分别是query和expressInit。二者的初始化是在[application.js]中的lazyrouter方法app.lazyrouter function lazyrouter() {if (!this._router) {this._router new Router({caseSensitive: this.enabled(case sensitive routing),strict: this.enabled(strict routing)});this._router.use(query(this.get(query parser fn))); // 最终调用的就是router.use方法this._router.use(middleware.init(this)); // 最终调用的就是router.use方法} }; 于是回答了我们刚才的第三个问题。7个中间件2个系统自带、3个APP级别的中间、2个路由级别的中间件2.2.2、router.route我们说过app.all、app.[Http Method]、app.route、router.all、router.[Http Method]经过一系列处理之后最终也是调用router.route的所以我们在demo中的express.js使用了两次app.get其最后调用了router.route我们看该方法核心实现proto.route function route(path) {var route new Route(path);var layer new Layer(path, {sensitive: this.caseSensitive,strict: this.strict,end: true}, route.dispatch.bind(route));layer.route route;this.stack.push(layer);return route; }; 这么简单的实现与上一个方法的实现唯一的区别就是多了new Route这个。通过二者对比我们可以回答上面的好几个问题初始化模型图Layer实例为什么分两种? 因为调用方式的不同决定了Layer实例的不同第二种Layer实例是挂载在route实例之下的。初始化模型图Layer实例中route字段什么时候会存在使用router.route的时候就会存在初始化实例图中圈2和圈3的route字段不一样而且name也不一样为什么圈2的Layer因为我们使用箭头函数不存在函数名所以name是anonymous但是圈3因为使用的router.route所以其统一的回调函数都是route.dispath因此其函数名字都统一是bound dispatch同时二者的route字段是否赋值也一目了然最后一个问题既然实例化route之后route有了自己的Layer那么它的初始化又是在哪里的初始化核心代码// router/route.js/Route.prototype[method] for (var i 0; i handles.length; i) {var handle handles[i];if (typeof handle ! function) {var type toString.call(handle);var msg Route. method () requires a callback function but got a typethrow new Error(msg);}debug(%s %o, method, this.path)var layer Layer(/, {}, handle);layer.method method;this.methods[method] true;this.stack.push(layer);} 可以看到新建的route实例维护的是一个path对应多个method的handle的映射。每一个method对应的handle都是一个layerpath统一为/。这样就轻松回答了最后一个问题了。至此再回去看初始化模型图相信大家可以有所明白了吧~2.3、express中间件的执行逻辑整个中间件的执行逻辑无论是外层Layer还是route实例的Layer都是采用递归调用形式一个非常重要的函数next()实现了这一切这里做了一张流程图希望对你理解这个有点用处我们再把express.js的代码使用另外一种形式实现这样你就可以完全搞懂整个流程了。为了简化我们把系统挂载的两个默认中间件去掉把路由中间件去掉一个最终的效果是((req, res) {console.log(I am the first middleware);((req, res) {console.log(I am the second middleware);(async(req, res) {console.log(I am the router middleware /api/test1);await sleep(2000)res.status(200).send(hello)})(req, res)console.log(second middleware end calling);})(req, res)console.log(first middleware end calling) })(req, res) 因为没有对await或者promise的任何处理所以当中间件存在异步函数的时候因为整个next的设计原因并不会等待这个异步函数resolve,于是我们就看到了sleep函数的打印被放在了最后面并且第一个中间件想要记录的请求时间也变得不再准确了~但是有一点需要申明的是虽然打印变得奇怪但是绝对不会影响整个请求因为response是在我们await之后所以请求是否结束还是取决于我们是否调用了res.send这类函数至此希望整个express中间件的执行流程你可以熟悉一二更多细节建议看看源码这种精妙的设计确实不是这篇文章能够说清楚的。本文只是想你在面试的过程中可以做到有话要说~接下去我们分析牛逼的Koa2这个就不需要费那么大篇幅去讲因为实在是太太容易理解了。3、koa2中间件koa2中间件的主处理逻辑放在了koa-compose也就是仅仅一个函数的事情function compose (middleware) {if (!Array.isArray(middleware)) throw new TypeError(Middleware stack must be an array!)for (const fn of middleware) {if (typeof fn ! function) throw new TypeError(Middleware must be composed of functions!)}/*** param {Object} context* return {Promise}* api public*/return function (context, next) {// last called middleware #let index -1return dispatch(0)function dispatch (i) {if (i index) return Promise.reject(new Error(next() called multiple times))index ilet fn middleware[i]if (i middleware.length) fn nextif (!fn) return Promise.resolve()try {return Promise.resolve(fn(context, dispatch.bind(null, i 1)));} catch (err) {return Promise.reject(err)}}} } 每个中间件调用的next()其实就是这个dispatch.bind(null, i 1)还是利用闭包和递归的性质一个个执行并且每次执行都是返回promise所以最后得到的打印结果也是如我们所愿。那么路由的中间件是否调用就不是koa2管的这个工作就交给了koa-router这样koa2才可以保持精简彪悍的风格。再贴出koa中间件的执行流程吧最后有了这篇文章相信你再也不怕面试官问你express和koa的区别了~参考koaexpresshttp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/87991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

董家渡街道网站建设蚌埠市建设工程质监站网站

试卷编号:0134 期末考 劳动法学试题答案 1、劳动法的调整对象 2、竞业限制 3.职工培训 4.行政责任 二、单项选择题(每题4分,共20分) 考生注意:必须将正确答案填入表格中,否则该…

企业网站空间多大合适网站qq访客统计

802.11w(PFM) Protected Management Frames,802.11w协议主要基于现有的对数据报文的加密形式,对管理帧进行类似的加密。802.11w需要加密的管理帧包括解关联帧、去认证帧及强壮Action帧。 802.11k(RRM) Radio Resource …

青岛外贸网站设计松江九亭网站建设

;GET和INCLUDE功能相同 ;功能:引进一个被编译过的文件。 GET option.inc GET memcfg.inc GET 2440addr.inc ;EQU为程序中的常量、标号等定义一个等效的字符名称 ;定义SDRAM工作在Refresh模式,SDRAM有两种刷新方式:autorefresh和selfrefresh&a…

做网站 就上凡科网中国网站设计欣赏

最大连续子矩阵算法 暴力求解不可取 或许可以从 O(n)复杂度内求解最大连续子数组的算法 得到灵感 O(n2)复杂度求最大连续子矩阵和算法: 创建一个新矩阵sum,sum[i][j]存放sun[i][0-j]的和每个候选矩阵由左上角matrix[i][j]和右下角的元素matrix[p][q]确定…

织梦cms 5.6网站地图合肥网站搭建公司哪家好

2024年认证杯C题的已经完成啦,包括参考论文,模型代码,分享给大家~ 问题分析 对于这些问题,我们首先需要确定影响日光辐射降低效应的关键参数,例如海盐气溶胶的浓度、粒子大小、分布以及喷洒高度和范围。同…

做字幕网站微信文章同步到wordpress

转自——http://blog.csdn.net/v_july_v/article/details/7041827 看到kmp是不是立即想到(*ο*) 哇~,那个东西啊,就是拿来放电影的那个啊! 哦,但是这里我们说的并不是那个东西,身为一名C选手,我…

公司网站在哪备案网页广告屏蔽

https://bbs.espressif.com/viewtopic.php?t75242#p100294 https://blog.csdn.net/ydogg/article/details/72598752

注册网站需要多少钱上海怎样做网站

路由器配置DMZ主机映射 光猫路由模式配置方法 光猫路由模式是用光猫进行拨号连接,所有设备通过光猫访问互联网,只需要设置光猫的DMZ主机映射地址为局域网主机即可 光猫桥接模式配置方法 光猫桥接模式,是穿透光猫,通过路由器拨…

网站制作南宁北京网络推广优化公司

交换机供电方式有很多,有集中供电,独立供电,220V交流电供电,PoE供电,随着不同场合的使用,特别是poe交换机使用非常多,但是出现的问题也不少。其中比较常见的就是PoE交换机供电突然不供电了&…

dede 网站地图模板htm知乎软文推广

最近在跨jenkins触发构建的时候发现不能触发相应的项目,报如下图错误 解决方案: 1、安装Build Authorization Token Root Plugin插件 安装完成后去配置API Token,用户列表,配置用户的API Token,生成后记得保存 2、项…

在哪下载.net网站作品PK10如何自己做网站

编者按: 转型一直在提,2018—2023年,实现数字化转型的企业仅占中国企业的10%,其中实现领军重塑的企业仅占2%。数据看起来并没有那么乐观! 新竞争格局下,企业需要直面挑战,定义新前沿&#xff0…

做门户网站用什么软件自己开发app要多少钱

我们提供的授权方案有三种:公网授权、加密狗授权、系统序列号SN授权。1. 公网授权如果您的应用服务器可以访问公网,即可使用这种方式。您的服务端在启动运行的时候,会主动访问我们的授权服务器进行合法认证。2. 加密狗授权如果您的应用服务器…

网站管理和维护的主要工作有哪些国外医院网站设计

一、this指向 this是函数运行时自动生成的一个内部对象,只能在函数内部使用 1. 指向全局变量 纯粹的函数调用 2. 作为对象方法的调用 对象调用某个函数,这个函数里面所包含的this也就指向使用这个函数的对象了 3. 函数构造新对象时调用 new 4. a…

gta5手机网站大全如何免费申请域名和网址

spring 工作流引擎几个月前,在处理一个公司项目时,我们需要开发REST服务,该服务用于根据客户端应用程序发送的数据发送电子邮件。 在开发此服务期间,我们决定创建简单的工作流引擎,该引擎将为发送电子邮件收费&#xf…

做暧昧免费视频大全网站标签在线设计平台

电商要怎么学?企业如何进行数字化转型打破市场僵局? 电商的学习需要从多个方面入手,首先需要了解电商的基本概念和原理,包括电商平台的运营模式、商品推广、客户服务等。此外,还需要掌握电商平台的操作技能&#xff0c…

门户网站设计要求学校网站建设策划书模板

在实际的应用中,我们常常需要实现在移动app和浏览器中点击返回、后退、上一页等按钮实现自己的关闭页面、调整到指定页面或执行一些其它操作的 需求,那在代码中怎样监听当点击微信、支付宝、百度糯米、百度钱包等app的返回按钮或者浏览器的上一页或后退按…

网站基本常识做优惠卷网站倒闭了多少钱

巨杉数据库 and mongo db ,分布式数据库, 转载于:https://www.cnblogs.com/feiyun8616/p/8178116.html

批量爆破wordpress重庆seo全网营销

保险如何防忽悠? 1.只买消费型保险,不要买返还型保险。许多人买保险被忽悠,就是因为买了返还型保险。返还型保险保费贵,保额低,收益又低。消费型保险保费便宜,保额高,杠杆高。 圣经有云:上帝的…

网站建设就找奇思网络广州网站建设制作的公司

①打开虚拟机的设置,找到网络设置。再启用网卡1,选择连接方式为Host-only,界面名称选择VirtualBox Host-Only Ethernet Adapter,设置如下图 提示: 1.对虚拟机网络设置,需要先关闭虚拟机; 2.这里…

湘潭城乡建设发展集团网站三星网上商城分期

MySQL DQL语法 DQL语法简介 DQL(Data Query Language)语句是一种用于从数据库中检索数据的语言。它主要用于数据查询和数据分析,而不是对数据库中的数据进行更新、插入或删除。DQL语句通常用于获取特定条件下的数据,进行聚合计算…