为什么向后端工程师推荐Node.js
时间:12-12
来源:互联网
点击:
1 2 3 4 5 6 7 8 9 | function main(){ var id = 1; var currentState = new Object(); currentState.person_id = id; db.query(select name from persons where id= + id, function(name,state){ output(person id: + state.person_id + , name: + name); },currentState);//注意currentState是db.query的第三个参数 } main(); |
记住这种重要的思路,我们再看看是否还能进一步的抽象?可以的,不过接下的动作之前,我们还要了解在JavaScript中一个函数也是一个对象。 一个函数实例fn除了函数体的定义之外,我们仍然可以在这个函数对象实例之本身扩展其他属性,如fn.a=1;受到这个启发我们尝试把需要保持的状态直接 绑定到函数实例上:
1 2 3 4 5 6 7 8 9 10 | function main(){ var id = 1; var currentState = new Object(); currentState.person_id = id; function onDataLoad(name){ output(person id: + onDataLoad.state.person_id + , name: + name); } onDataLoad.state = currentState ;//为函数指定state属性,用于保持状态 db.query(select name from persons where id= + id, onDataLoad); } |
我们做了什么?生成了currentState对象,然后在函数onDataLoad定义时,将currentState绑定给 onDataLoad这个函数实例。那么在onDataLoad运行时,就可以拿到定义时的state对象了。JavaScript的闭包特性就是内置了 这个过程而已。
在每个JavaScript函数运行时,都有一个运行时内部对象称为Execution Context,它包含如下Variable Object(VO,变量对象), Scope Chain(作用域链)和”this” Value三部分。如图:
![](../img/eep-analog/analog-26877rbuzqefmfgw.jpg)
其中变量对象VO,包含了所有局部变量的引用。对于main函数,局部变量”id”存储在VO.id内。看起来用VO来代替我们的 currentSate最合适了。但main函数还可能嵌套在其他函数之内,所以我们需要ScopeChain,它是一个包含当前运行函数VO和其所有父 函数scope的数组。
所以在这个例子中,在onDataLoad函数定义时,就为默认为其绑定了一个[[scope]]属性指向其父函数的 ExecutionContext的ScopeChain。而当函数onDataLoad执行时,就可以通过[[scope]]属性来访问父函数的VO对 象来找到id,如果父函数的VO中没有id这个属性,就再继续向上查找其祖先的VO对象,直到找到id这个属性或到达最外层返回undefined。也正 是因为这个引用,造成VO的引用计数不为0,在走出作用域时,才不会被垃圾回收。
很多朋友觉得闭包较难理解,其实我们只要能明确的区分函数定义和函数运行两个时机,那么闭包就是让函数在运行时能够访问到函数定义时的所处作用域内的所有变量,或者说函数定义时能访问到什么变量,那么在函数运行时通过相同的变量名一样能访问到。
关于状态保持是本文的重点,在我看到的多数Node.js的介绍文章中并没有详解这里,我们只是知道了要解决阻塞问题,但是JavaScript解决阻塞问题的优势到底在哪里,作为一名前端工程师,我想有必要花一些篇幅详细解释一下。
而之所以我叫它”状态保持”因为还有一个非常相似的场景可以类比:
用户从A页面提交表单到B页面,如果提交数据校验不通过,则需要返回A页面,同时保持用户在A页面填写的内容并提示用户修改不对的地方。从提交到校验出错再返回继续填写是一个包含网络交互的异步过程,这相当于填写表单这个任务过会儿再继续。
在传统网页开发中,用户的状态通过请求传递到服务端,交由后端状态保持(类似交给db.query的currentSate)。而使用Ajax的网 页,因为并未离开原页面,那么服务端只要负责校验用户提交的数据是否正确即可,发送错误,返回错误处相关信息即可,这就是所谓前端状态保持。可以看到这个 场景里边服务端做的事情变少了,变纯粹了。正如我们的例子中db.query不再存储转发第三个state参数,变得更在轻量。
我们看到通过JavaScript函数式语言特性,匿名函数支持和闭包很漂亮的解决了同步编程到异步编程转化过程中遇到的一系列最重要的问题。但JavaScript是否就是最好的?这就要回答我们引用新技术时需要考虑的最后一个问题了。
使用Node.js是否带来额外的困扰,如何解决?
Node.js性能真的是最好么?不用比较我们也可以得到结论,Node.js做无阻塞编程性能较难做到极致。何为极致?处理一个请求需要占用多少 内存,多少cpu资源,多少带宽,有丁点浪费就不是极致。阻塞式编程浪费了大量进程资源只是在等待,导致大量内存和cpu的浪费。在这方面Node.js 好很多,但也正是因为一些闭包等JavaScript内建机制也会导致资源的浪费,看下面的代码:
- js触发器常用芯片(04-25)
- 《讲述.电子人》:电子工程师支教路,过程远比结果重要(02-26)
- 满足所有设计的电量计(07-12)
- 想在理工科领域有所成就?看看TI工程师怎么说(08-29)
- 工程师,您所不知道78%硬件失效的罪魁祸首(02-05)
- 教你成为优秀的模拟集成电路设计工程师(02-26)