提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|行业资讯|编辑:龚雪|2017-03-01 11:34:33.000|阅读 150 次
概述:在这篇中,笔者会列出 2017 年成为更好 Node 开发者的技巧的大纲。这些技巧一部分是在具体实践中总结得出的,一部分借鉴了 Node 和 npm 优秀模块开发者的经验。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
注意: 这篇文章之前的标题是 “来自平台大神的最佳实践分享”。文章内容是经过实际的测试和试验写出,但并非 2017 年最新技巧。 虽然,Node 大神分享的最佳经典实践在 2017 年,2018 年甚至 2019 年都会受用,但一些尖端功能,像 async/await, promises 并没有涵盖在内。因为这些新特性不在 Node 核心代码中,也不如 npm 和 Express 流行。文章第二部分,我将介绍此文章的性质。
我开始作为全职Node开发是在2012年,当我加入了Storify公司。 从那时起,我从没有回头或者觉得挂念Python,Ruby,Java和PHP——这些贯穿我之前十年web开发工作的语言。
Storify对我来说是一份有趣的工作,因为不像大多数公司, Storify所有的项目运行(也许今后依旧)都是使用Javascript。你看,大多数公司,尤其是大公司如贝宝(PayPal)、沃尔玛(Walmart)、或第一资本(Capital One),只是使用Node作为他们堆栈的某部分。通常他们使用它作为API途径或一个业务流程层。这也是不错的,但是对于一个软件工程师来说,没有什么比完全沉浸在一个Node环境中更棒的了。
我这篇博客中,我会列出 2017 年成为更好 Node 开发者的技巧的大纲。这些技巧一部分是我在具体实践中总结得出的,一部分借鉴了 Node 和 npm 优秀模块开发者的经验。主要内容如下:
下面,让我们对每项内容都进行一下了解吧~
避免复杂性
npm 的作者 Isaac Z. Schlueter 写了一些模板,我们可以看下。例如, 用 在模块中强制实施 JavaScript 严格模式,只需要三行代码:
var module = require('module') module.wrapper[0] += '"use strict";' Object.freeze(module.wrap)
那么,为什么要避免复杂性呢? 美国海军传说中,有一句很著名的话:化繁为简,返璞归真(或理解为“编码的方式简单点,傻蛋!”)事实证明,人类大脑一次只能记住 5 项至 7项的内容,这就是此处要求简单的原因。
缩小代码模块,有利于你和开发者更好地理解代码,你也能更好地进行测试。参考以下示例:
app.use(function(req, res, next) { if (req.session.admin === true) return next() else return next(new Error('Not authorized')) }, function(req, res, next) { req.db = db next() })
或如下代码:
const auth = require('./middleware/auth.js') const db = require('./middleware/db.js')(db) app.use(auth, db)
我相信大多数的读者都更喜欢第二个示例,尤其是在名称可以自解释时。当然,在你写代码时,你能理解它的运行方式。或许,你还会为能将如此多的方法用在一行代码中而沾沾自喜。但是,代码不会说话啊。如果你把代码写的复杂而严谨,当你时隔六个月再来看,或者某天你睡迷糊了或喝醉了来看,理解起它们来会非常困难,更不要说根本不了解其算法和复杂性的同事了。保持简单,这一准则在使用 Node 异步方式的时候特别受用。
有一种 ,不过它只影响了依赖公共注册表的项目,并在 11 分钟之后重新发布。最小化所带来的益处远大于其缺点。而且,npm 已经,任何重要的项目都应该使用缓存或私有注册中心(作为临时解决方案)。
使用异步代码
同步代码确实在 Node 中有一个(低的)位置。 它主要用于编写 CLI 命令或与 Web 应用程序无关的其他脚本。Node 开发者主要构建 Web 应用程序,因此他们使用异步代码,以避免阻塞线程。
例如,这可能是可行的,如果我们只是建立一个数据库脚本,而不是一个系统来处理并行/并发任务:
let data = fs.readFileSync('./acconts.json') db.collection('accounts').insert(data, (results))=>{ fs.writeFileSync('./accountIDs.json', results, ()=>) })
但当建立一个Web应用程序时,这样写会更好:
app.use('/seed/:name', (req, res) => { let data = fs.readFile(`./$.json`, ()=>{ db.collection(req.params.name).insert(data, (results))=>{ fs.writeFile(`./$IDs.json`, results, ()=) }) }) })
区别就在于你是写并发系统(长期运行)还是非并发系统(短期运行)。根据实践经验,我们通常在 Node 中使用异步代码。
避免阻塞请求
Node 有个简单的模板加载系统,它使用的是 CommonJS 模板规范。它内置的 require 函数是将单独存放的模板包含进来的简易方式。不像 AMD/requirejs,Node/CommonJS 的模板加载方式是同步的。require 的工作原理:导入在模板或文件中导出的内容。
const react = require('react')
大多数开发者都不知道 require 有缓存。因此,只要解析的域名没有变化(在 nmp 模板中是没有的), 模块中的代码会只执行一次并将结果保存在一个变量中(同一进程内)。这是一个很不错的优化。然而,即使在缓存的情况下,你也最好把 require 语句放在前面。 看看下面的代码,在真正进入路由的时候才加载 axios 模块。/connect 路由出乎预料的慢,因为它在导入模块的时候才开始请求文件:
app.post('/connect', (req, res) => { const axios = require('axios') axios.post('/api/authorize', req.body.auth) .then((response)=>res.send(response)) })
更好更高效的方式是服务器启动后就加载模块,而不是在路由中:
const axios = require('axios') const express = require('express') app = express() app.post('/connect', (req, res) => { axios.post('/api/authorize', req.body.auth) .then((response)=>res.send(response)) })
了解 require 可被缓存
我在上面提到过 require 可缓存,但有趣的是我们可以在 module.exports 外部进行编码,比如:
console.log('I will not be cached and only run once, the first time') module.exports = () => { console.log('I will be cached and will run every time this module is invoked') }
知道有些代码只运行一次,你可以将这一特点作为优势。
时刻检查错误
Node 不是 Java,在 Java 中,你可以抛出错误,因为大多数时候,当你发现错误时,你会中止应用程序的运行。并且,在 Java 中,你可以通过单独的 try...catch 处理多个错误。
但 Node 不是这样。因为 Node 使用的是事件循环和异步执行,在错误发生时,任何错误都与错误处理程序的上下文分离(比如 try...catch)。下述代码在 Node 中无效:
try { request.get('/accounts', (error, response)=>{ data = JSON.parse(response) }) } catch(error) { // Will NOT be called console.error(error) }
但 try...catch 也可在 Node 同步代码中使用。因此,这是重构前面代码段的更好的方式:
request.get('/accounts', (error, response)=>{ try { data = JSON.parse(response) } catch(error) { // Will be called console.error(error) } })
如果我们不能将 request 调用放在 try...catch 块中,我们就不能处理来自 request 的错误。Node 开发者采用提供包含 error 参数的回调来解决这个问题。这样你需要在每个回调中手工处理错误。你需要检查 error(确保它不是 null),然后将相应的错误消息显示给用户或者客户端,并记录下来。也可以通过调用栈中的 callback 往回传(如果你有回调,而且调用栈上还有另一个函数)。
request.get('/accounts', (error, response)=>{ if (error) return console.error(error) try { data = JSON.parse(response) } catch(error) { console.error(error) } })
你还可以使用 库。 你可以使用以下代码来避免在无数回调中出现手动检查的误差。 (Hello, ).
var ok = require('okay') request.get('/accounts', ok(console.error, (response)=>{ try { data = JSON.parse(response) } catch(error) { console.error(error) } }))
返回回调或使用 if … else
Node 是并发的。因此它有个特点就是,如果不加以注意,就会出现 bug。安全起见,我们使用 return 语句终止执行:
let error = true if (error) return callback(error) console.log('I will never run - good.')
避免由于错误的控制流导致的一些无意的并发(和失败操作)。
let error = true if (error) callback(error) console.log('I will run. Not good!')
确保返回一个回调,以防止继续执行。
监听错误事件
几乎所有的 Node 类/对象都扩展了事件发射器(观察者模式)并发出错误事件。 在错位被破坏之前,这给开发人员提供了捕获错误并处理的机会。
养成使用 .on() 为错误创建事件侦听器的好习惯
var req = http.request(options, (res) => { if (('' + res.statusCode).match(/^2\d\d$/)) { // Success, process response } else if (('' + res.statusCode).match(/^5\d\d$/)) // Server error, not the same as req error. Req was ok. } }) req.on('error', (error) => { // Can't even make a request: general error, e.g. ECONNRESET, ECONNREFUSED, HPE_INVALID_VERSION console.log(error) })
了解 npm
很多 Node 开发者和前端开发者都知道—— save(npm install 参数)可以安装一个模板,但要在 package.json 记录模板的版本。当然,还有 save-dev, 用于在 devDependencies 添加记录 (记录生产中不需要的模板)。但你知道用 -S 和 -D 代替 --save 和 --save-dev 吗?你不妨试试。
在安装模块的时候,去删除 -S 和 -D 为你添加的那些 ^ 记号。它们非常危险,因为它们允许 npm install(或简写为 npm i)从 npm 库中拉取最新的小版本(语义化的版本号中的第2个数)。比如从 v6.1.0 到 v6.2.0 就是一个小版本发布。
npm 团队信任 ,但你不能。他们加上 ^ 符号是因为他们相信开源作者不会在小版本中引入破坏性的修改。然而明眼人都知道它是不可靠的。你应该锁定版本号,最好使用 shrinkwrap:npm shrinkwrap 创建一个包含依赖的具体版本的新文件。
结语
这篇博客只是第一部分,其中已经涵盖了很多内容,从回调函数和异步代码的使用,到错误的检查和依赖的锁定。希望这篇文章能给你带来新的启示。(作者:Azat Mardan ;翻译:可译网)
更多行业资讯,更新鲜的技术动态,尽在。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
通过提供强大的3D CAD数据访问工具并适用于桌面、移动和Web的高级环境3D可视化发动机,HOOPS在提升造船设计和制造流程的效率方面发挥了重要作用。
HOOPS Luminate在汽车行业中的应用具有广泛的潜力和深远的影响。它通过提供高效的3D可视化、虚拟装配与拆解、性能分析、客户定制等功能,帮助汽车制造商在设计、生产和销售过程中提升效率、降低成本并提高产品质量。
在不断发展的软件开发世界中,使工具和框架与最新的平台版本保持同步至关重要,欢迎查阅~
全球航运业对国际贸易至关重要,全球 90% 以上的商品通过海运运输。准确监控和控制这些集装箱的移动对于维持高效的供应链至关重要。手动输入集装箱号码是这一程序的关键部分,它带来了相当大的挑战,例如人为错误和效率低下。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢