问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

2015 nodejs还会火热吗

发布网友 发布时间:2022-03-24 20:06

我来回答

2个回答

懂视网 时间:2022-03-25 00:27

node.js不火了的原因是:

  

  1、NodeJS不是并没有大火,有历史包袱的公司还在用着一直用的语言,没历史包袱的选什么的都有。

  

  2、用JS做後台的一大好处是先後端逻辑共用,可以把前端开发者当後台的,JS这种十天的产物,NodeJS不是为後台而生。

  

  3、node.js就是服务器端用的javascript,可以用来写服务器程序。apache跟node.js根本不是一类东西。和node.js相似的是python的twisted、ruby的event machine。而且node.js不可能“旨在使 php web 应用程序更容易伸缩”。

  

  

热心网友 时间:2022-03-24 21:35

这段代码的问题是在上面两个语句之间,在整个数据查询的过程中,当前程序进程往往只是在等待结果的返回.这就造成了进程的阻塞.对于高并发,I/O密集行的网络应用中,一方面进程很长时间处于等待状态,一方面为了应付新的请求不断的增加新的进程.这样的浪费会导致系统支持QPS远远小于后端数据服务能够支撑的QPS,成为系统的瓶颈.而且这样的系统也特别容易被慢链接攻击(客户端故意不接收或减缓接收数据,加长进程等待时间).
如何解决阻塞问题
解决这个问题的办法是,建立一种事件机制,发起查询请求之后,立即将进程交出,当数据返回后触发事件,再继续处理数据:

Js代码
//定义如何后续数据处理函数
function onDataLoad(name){
output("name");
}
//发起数据请求,同时指定数据返回后的回调函数
db.query("select name from persons where id=1",onDataLoad);

我们看到按照这个思路解决阻塞问题,首先我们要提供一套高效的异步事件调度机制.而主要用于处理浏览器端的各种交互事件的JavaScript.相对于其他语言,至少有两个关键点特别适合完成这个任务.
为什么JS适合解决阻塞问题
首先JavaScript是一种函数式编程语言,函数编程语言最重要的数学基础是λ演算(lambda calculus) -- 即函数可以接受函数当作输入(参数)和输出(返回值).
函数可以作为其他函数的参数输入的这个特性,使得为事件指定回调函数变得很容易.特别是JavaScript还支持匿名函数.通过匿名函数的辅助,之前的代码可以进行简写如下.

Js代码
db.query("select name from persons where id=1",function(name){
output(name);
});

还有一个关键问题是,异步回调的运行上下文保持(称状态保持),我看一段代码来说明何为状态保持.

Js代码
//传统同步写法:将查询和结果打印抽象为一个方法
function main(){
var id = "1";
var name = db.query("select name from persons where id=" + id);
output("person id:" + id + ", name:" + name);
}
main();

前面的写法在传统的阻塞是编程中非常常见,但接下来进行异步改写时会遇到一些困扰.

Js代码
//异步写法:
function main(){
var id = "1";
db.query("select name from persons where id=" + id,function(name){
output("person id:" + id + ", name:" + name);//n秒后数据返回后执行回调
});
}
main();

细心的同学可以注意到,当等待了n秒数据查询结果返回后执行回调时.回调函数中却仍然使用了main函数的局部变量"id",而"id"已经在n秒前走出了其作用域,这是为什么呢?熟悉JavaScript的同学会淡然告诉您:"这是闭包(closures)~".
其实在复杂的应用中,我们一定会遇到这类场景.即在函数运行时需要访问函数定义时的上下文数据(注意:一定要区分函数定义时和函数运行时这样的字眼和其代表的意义,不然很快就会糊涂).而在异步编程中,函数的定义和运行又分处不同的时间段,那么保持上下文的问题变得更加突出了.
在这个例子中,db.query作为一个公共的数据库查询方法,把"id"这个业务数据传入给db.query,交由其保存是不太合适的.但聪明的同学们可以抽象一下,让db.query再支持一个需要保持状态的数据对象传入,当数据查询完毕后可以把这些状态数据原封不动的回传.如下:

Js代码
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;受到这个启发我们尝试把需要保持的状态直接绑定到函数实例上.

Js代码
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对象了.而闭包就是内置了这个过程而已.

在每个函数运行时,都有一个运行时对象称为Execution context,它包含如下variable object(VO,变量对象),scope chain(作用域链)和thisValue三部分.详见ECMA-262 JavaScript. The Core

其中变量对象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,在走出作用域时,才不会被垃圾回收.
很多人觉得闭包很难理解,其实我们只要能明确需要区分函数定义和函数运行这两个时机,记住闭包让函数在运行时能够访问到函数定义时的所处作用域内的所有变量.或者说函数定义时能访问到什么变量,那么在函数运行时通过相同的变量名一样能访问到.

关于状态保持是本文的重点,在我看到的多数NodeJS的介绍文章,并没有详解这里,我们只是知道了要解决阻塞问题,但是JavaScript解决阻塞问题的优势在哪里,作为一个前端开发,我想有必要详细解释一下.

其实说到状态保持还有一个类似的场景,比如用户从A页面提交表单到B页面,如果提交数据校验不通过,则需要返回A页面,同时保持用户在A页面填写的内容并提示用户修改不对的地方.从提交到返回显示这也是一个包含网络交互的异步过程.传统网页,用户的状态通过请求传递到服务端,交由后端状态保持(类似交给db.query的currentSate).而使用Ajax的网页,因为并未离开原页面,那么服务端只要负责校验用户提交的数据是否正确即可,发送错误,返回错误处相关信息即可,这就是所谓前端状态保持.可以看到这个场景里边服务端做的事情变少了,变纯粹了.正如我们的例子中db.query不再存储转发第三个state参数,变得更轻量.

我们看到通过JavaScript函数式语言特性,匿名函数支持和闭包很漂亮的解决了同步编程到异步编程转化过程中遇到的一系列最重要的问题.但JavaScript是否就是最好的?这就要回答我们引用新技术时需要考虑的最后一个问题了
使用NodeJS是否带来额外的困扰,如何解决
性能真的是最好么?不用比较我们也可以得到结论NodeJS,做无阻塞编程性能较难做到极致.何为极致,处理一个请求需要占用多少内存,多少cpu资源,多少带宽,如果有浪费就不是极致.阻塞式编程浪费了大量进程资源只是在等待,导致大量内存和cpu的浪费.NodeJs好很多,但也正是因为一些闭包等JS内建机制也会导致资源的浪费,看下面的代码

Js代码
function main(){
var id = "1";
var str = "..."; //这里存储一个2M的字符串
db.query("select name from persons where id=" + id,function(name){
output("person id:" + id + ", name:" + name);//n秒后数据返回后执行回调
});
}
main();

直到数据查询完成,变量str所使用的2M内存不会被释放,而str保持下去可能并没有意义.前面已经解释过闭包的原理,闭包并没有智能到只包起来今后可能被访问到的对象.即使不了解闭包的原理,也可以通过一段简单脚本验证这点:

Js代码
function main(){
var id = "1";
var str = "..."; //这里存储一个2M的字符串
window.setTimeout(function(){
debugger; //我们在这里设置断点
},10000)
}
main();

我们在回调函数当中只设置一个断点,并不指明我们要访问哪个变量.然后我们在控制台监视一下,id和str都是可以拿到的.(此处结论不严谨,各种新浏览器已经就此做了相关优化,详见评论2楼,特别是2楼给出的详细测试报告的连接)
所以我来不负责任的预测一下,性能极端苛刻的场景,无阻塞是未来,但无阻塞发展下去,或者有更轻量的脚本引擎产生(lua?),或者V8JS引擎可能要调整可以disable闭包,或者我们可以通过给JS开发静态编译器在代码发布前优化我们的代码.

我之前谈到过JS静态编译器:"如果给JS代码发布正式使用前增加一个编译步骤,我们能做些什么",动态语言的实时编译系统只完成了静态语言编译中的将代码转化为字节码的过程,而静态语言编译器的额外工作,如接口校验,全局性能优化等待.所以JS也需要一个静态的编译器来完成这些功能,Google利用ClouserComplier提供了系列编译指令,让JS更好的实现OO编程,我来利用静态编译器解决一些JS做细粒度模块化引入的性能方面的问题.而老赵最近的项目JSCEX,则也是利用JS发布前的编译环节重点解决异步编程的代码复杂度问题.
我们习惯于阻塞式编程的写法,切换到异步模式编程,往往对于太多多层次的callback嵌套弄得不知所措.所以老赵开发的JS静态编译器,借鉴F#的Computation Expressions,让大家遵守一些小的约定后,能够仍然保持同步编程的写法,写完的代码通过JSCEX编译为异步回调式的代码再交给JS引擎执行.
如果这个项目足够好用,那就也解决了一个使用NodeJS这种新技术,却加大编程复杂度这个额外引入的困扰.甚至可以沿着这个思路,在静态编译阶段优化内存使用.

NodeJS还要解决什么问题
说了这么多,无阻塞编程要做的还远不止这些.首先需要一个高效的JS引擎,高效的事件池和线程池.另外几乎所有和NodeJS交互的传统模块如文件系统,数据访问,HTTP解析,DNS解析都是阻塞式的,都需要额外改造.
正是NodeJS作者极其团队,认清问题问题以及JS解决这些问题方面的优势.基于高效的V8 JavaScript引擎,贡献了大量的智慧和精力解决上述大部分问题后才有NodeJS横空出世.
当前Node社区如此火热,千余开源的NodeJS模块,活跃在WebFramework,WebSocket,RPC,模板引擎,数据抓取服务,图形图像几乎所有工程领域.
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
陈八两面馆的什么面最好吃? 杭州湾跨海大桥可以骑行吗 杭州湾跨海大桥上能骑车吗? ...不知道可不可以骑自行车,又需要做哪些准备,谢谢各位资深人士了... 激光祛痘坑的效果如何? 口述:3个闺密分享1个“软饭男” 骚气文案暗示-推荐65句 三个男人怎么晒朋友圈 任钊的介绍 请问德阳青依江路口到德阳中级人民法院坐几路公交车 为什么 Node,js 这么火,而同样异步模式 Python 框架 Twisted 却,大部分 为什么 Node.js 很糟糕 为什么前端精通Node.Js的人这么少 NodeJS会是昙花一现吗 node.js为什么不火了 2019年nodejs凉了吗?凉到什么程度了? 文件夹的扩展名都有哪些? 文件的扩展名都都代表什么含义? 请问各文件扩展名代表什么意思? 文件夹的扩展名是什么 什么叫做文件的扩展名?可以更改扩展名吗? 文档文件的扩展名是什么? 文件扩展名是什么意思????? 什么是文件基本名和文件扩展名 什么叫文件的扩展名? 文件的扩展名是什么意思 什么是文件的扩展名扩展名有什么作用 什么是文件的扩展名? 文件的"主名"和"扩展名"分别表示什么意思? 50、一个文件的扩展名通常表示( )。 A. 文件的的版本 B.文件的类型 C.文件的大小 D.完全由用户自己决定 为什么没人推荐用 JavaScript/Node.js 做机器学习和数据分析 Node.js被高估了吗 为什么 Node.js 后端程序员这么难招 为什么来自Node.js社区的stylus人气比不上sass和less 为什么Node.js会这么火 大家觉得node.js的发展前景怎么样 node.js与php相比有哪些优缺点?未来会替代php成为最好的语言吗 Node.js 这么重要,为什么大学教育没有开课? 登陆cf游戏需要人脸识别如何操作 微信被限制如何让变成人脸识别解封? 手机通话记录怎么恢复 换一个华为手机通话记录没有了怎么找回? 如何找回电话通话记录 手机怎么样恢复通话记录软件 手机通话记录没有了,怎么恢复? 删除掉的通话记录怎么恢复 荣耀30pro怎么设置虚拟键 华为mate30手机如何虚拟位置 华为mate30pro的虚拟按键能关闭吗? 华为mate30pro退出键在哪里