前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑走偏锋!domain模块居然还能这样用!

剑走偏锋!domain模块居然还能这样用!

作者头像
TSW
发布2018-07-03 14:59:34
1.1K3
发布2018-07-03 14:59:34
举报
文章被收录于专栏:TSWTSW

前言

虽然domain模块目前处于弃用(Deprecated)状态。但经过我们多年来对domain模块的使用,并没有什么问题。同时node8.0之后,出现了async_hook模块,domain模块已经完全使用async_hook模块重写了,因此再也不用担心domain模块被移除后无法使用。

简单介绍domain模块

一个domain对象,可以将多个异步操作归为一组。当这些操作抛出Error事件时,domain对象可以捕捉到这些Error事件,并且不丢失上下文。

举个例子!

一般我们会用try-catch来捕捉异常,但如果在try里头有异步操作并且异步操作里抛出异常,那么这时候catch里面并不能捕捉到这个异常,比如:

这种情况在一个HTTP Server中比较常见。比如用户请求一个数据,node端接收到请求发起一个异步操作读取数据库。如果异步操作里面代码写得不够完善,抛出了异常,这时候因为无法捕捉到这个异常,所以没法拿到上下文(这里指用户的request与response)及时给用户返回错误信息。这样体验是不能接受的。

那么怎么解决这个问题呢? 可以引入domain模块。

就像图片代码所示,每一个HTTP请求来的时候创建一个domain对象。后续的操作全部在domain对象中执行,这样即使有异步操作出现异常,也能捕捉到这个异常并且不丢失上下文。

彩蛋!利用domain模块实现HTTP请求生命周期的全局变量

有仔细阅读过domain模块文档的同学可能会发现:

process.domain 这个全局变量会自动指向当前作用中的domain对象。

利用这一个特性,我们可以把一个HTTP请求生命周期内需要共享的变量挂载到domain对象上。这样在同一个请求里面的所有操作都可以通过domain对象获取到共享的变量,而再不需要通过函数参数的方式透传。

如代码所示,handle函数不需要通过外部传入res对象,也能获取到当前请求的res对象。这在代码结构非常复杂的时候非常实用!

window对象的诞生

就像浏览器环境有一个全局的window对象,TSW框架根据domain模块的特性也创建一个全局的window对象。

这里很关键的一点是利用了Object.defineProperty来创建window对象。这样window的值永远返回的是当前domain对象上的window对象。通过这种方式,在TSW框架内的编写的代码可以直接使用window变量获取到request和response对象,非常方便。

全息日志

有了一个HTTP请求声明周期的全局变量,我们实现按HTTP请求这一维度聚合日志就变得可能并且是一件很简单的事。这里直接上一张日志图:

(部分信息因安全问题做了隐藏处理)

全息日志功能支持通过用户uid快速查询用户的日志。当前这一功能也集成到tsw开放平台(tswjs.org)中,欢迎大家试用。

关于domain模块被弃用的一些思考

按nodejs的文档所说,使用domain模块之后,大家很容易就会忽略异常了。但是出现异常如果不作处理是很容易有内存泄露,这样就导致nodejs服务的不稳定。不过根据我们的实际使用, 只要每次请求结束后(包括出现异常)及时清除掉domain的引用。内存泄露的问题是不存在的。

另外根据官方文档所说,现在也没有其他方案可以完全代替domain模块,因此也不会贸然废弃domain模块。同时我们发现,从node8.0版本之后,node出现了async_hook模块,并且将domain模块用async_hook模块重写了。这意味着,以后即使官方将domain模块废弃了,第三方也可以使用async_hook模块实现一个domain模块继续使用。

所以不用担心domain会被废除,大胆的使用domain模块吧!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 tswjs 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档