龙空技术网

「fastify项目实战」投票Web应用之三

计算机科学技术 160

前言:

而今咱们对“js投票代码”都比较注重,小伙伴们都想要了解一些“js投票代码”的相关文章。那么小编也在网上收集了一些对于“js投票代码””的相关知识,希望各位老铁们能喜欢,咱们一起来学习一下吧!

项目介绍

「fastify项目实战」投票Web应用之一

「fastify项目实战」投票Web应用之二

第一篇文章《投票Web应用之一》介绍了投票系统的基础功能,第二篇文章《投票Web应用之二》介绍了用户系统功能。到目前为止,这两个功能还是相对独立的。我们需要构建的系统是将这两个信息关联起来,即用户投票时,除了要记录下投票条目所得到的票数之外,还需要记录下是哪一个用户对此条目进行了投票。因此,执行投票之前,用户必须首先完成登录操作,之后在执行投票相关的操作时,就可以附加一些信息一并发送给服务器,服务器根据提供的信息和已经存在的投票记录进行判断这一次投票该如何处理。

代码重构

为什么要重构代码?我们的项目首先是实现了一个投票的最小系统,之后又加入了用户功能,以后有可能会加入更多的功能。现在的做法是将所有的代码全部编写在index.js文件,目前,这个文件的代码行数将近200行,而且,我们还将投票功能和用户功能全都在这个文件中实现,随着功能的增多和业务逻辑的不断完善,代码量会快速地变大,因此,我们需要考虑对代码进行重构,将独立的功能实现模块化。

fastify框架提供了一种称之为封装模型(encapsulation model)的概念,在fastify框架中,一切皆为插件(plugin),我们可以通过创建不同的插件完成对功能的封装。fastify框架中的插件其实是一个含有三个参数的函数:第一个参数为fastify实例,第二个参数为配置对象,第三个参数为插件准备就绪时的回调函数。如下图1所示:

图1

如果你需要使用这个插件,那么,通过调用统一的接口方法register将插件注册到框架中就可以了。fastify与其它框架所不同的是,调用register函数时,它会自动创建一个fastify实例的上下文,这个上下文中的数据默认情况下只允许它的子实例查看,它的兄弟级别和父类及其以上的实例是无法查看它的数据的,这是fastify框架的一个显著特点。

重构用户路由

原用户相关的代码位于index.js文中的第27-106行,如图2所示,

图2

我们现在需要将这些代码全部移至到一个插件中。首先创建一个目录,将其命名为routes,并在这个routes目录下创建一个文件,名称为user.mjs,按照图1所示,创建一个标准的插件函数,将其命名为user,将数据users放置到插件函数外面,其它的代码放置到插件函数内。修改完成后user.mjs的内容,如图3所示

图3

完成上述的操作之后,第一个插件user就算是构建完成了。我们接下来介绍如何使用这个插件。删除index.js文件中第27-106行的代码,这些代码已经由user插件实现了。为了在index.js文件中使用user插件,我们在index.js文件的头部导入这个模块文件,如图4所示

图4

第2行代码将插件user导入至当前index.js文件中,之后可以调用fastify实例的register方法将其注册到当前的上下文中,如图5所示

图5

第9行代码将user插件注册到了ff这个实例中,这样我们就完成了第一个插件的创建和注册。

重构投票路由

将投票的代码转化为投票插件的操作与上述用户插件的操作相同,这里我们不再一步一步地描述其转换过程,最终的结果是在目录routes下面创建了一个vote.mjs文件,在此文件中定义路由插件的具体代码,之后在index.js文件中注册vote插件。完成后index.js文件中的代码如下图6所示。

图6

图6中第3行代码导入投票插件,第10行代码注册投票插件,启动程序之后,就可以使用客户端进行测试了,其功能与之前所实现的功能完全一致。

发送用户信息

上一篇文章中,用户登录后,服务器会向客户端发送一条响应信息,这个响应信息含有一个token数据,如下图7所示。

图7

图7中客户端执行的是用户登录请求,其响应信息如图7底部图示,它含有用户的userId和token数值,客户端不必清楚这个token具体包含哪些内容,只需要在每次向服务器发送请求时携带上它就可以了,服务器会从token中提取感兴趣的数据。

客户端投票

执行投票请求(/votes/:voteId/vote)与之前的请求所不同的是:现在需要客户端提供一个token信息,我们将这个token信息放置在消息头字段中。如果执行投票请求的时候,客户没有提供此token信息,那么,服务器会返回如下的错误信息:

图8

我们以图7中的已登录用户Id和token为例,构建一个投票请求,其内容如下图9,显示了postman中设置的头信息

图9

当用户1003第一次发送投票请求时,其返回值的count字段内容变为了11,再次发送请求时,这个count字段值将不再变化,我们接下来看一下服务器是如何实现这样的功能的。

投票响应

为了在服务器端能够辨识每一个客户端的投票请求,我们需要将客户的id和投票条目的id通过冒号(:)进行分割作为一个“ID对”字符串,并将其存储在一个集合中,每次请求时,服务器依据客户端提供的请求信息构建出对应的“ID对”字符串,如果这个“ID对”字符串存在,则表明此用户已经投票,不需要再次投票;否则,这个投票条目的得票数加1,并将“ID对”字符串保存至集合中。图10展示了投票的代码逻辑。

图10

图10中第64行代码使用了请求对象的headers字段,图9所示,我们在客户端的投票请求头中添加了一个token字段,通过使用headers[字段名]的方式,服务器就获取到了这个token值,之后会判断这个token是否真实存在,如果token不存在,那么就认为是一个非法的请求。如果这个请求合法,那么,第68行代码会从token中提取出用户Id值,使用这个Id值和第63行获取到的voteId值,在第74行判断由这两个Id所构成的“Id对”字符串是否存在于当前的集合中,如果已经存在了,那么仅仅返回这个投票的结果,而不会执行第75-76行代码。

至此,我们通过使用token的方式实现了同一个用户只能对同一个条目执行一次投票的目的,使用插件技术将用户路由和投票路由进行了封装。但是项目中的其它资源依旧是可以随意访问的,如果我们采用图10中第64-67行代码对每一个投票相关的函数添加同样的逻辑处理,看上去代码就会出现重复,fastify框架是如何解决这类问题的呢?我们下一篇文章中对此问题做详细介绍,谢谢各位阅读,我们下一篇文章见!

「fastify项目实战」投票Web应用之一

「fastify项目实战」投票Web应用之二

标签: #js投票代码