JAVA程序员如何转node_01

背景

先介绍一下背景吧,笔者在大学期间主要学的是JAVA,但学的也不是很深,就会基本的课设程度的网站编写水平。找工作的时候公司面试并没有问语言相关的东西(我当时也没注意),等到进来之后才知道会统一进行培训,学习其他的语言。算机缘巧合吧,就选择了node方向。经过了一段时间的学习与实践,目前应该可以说入了个门了,故分享一下现阶段的学习心得,可以纯粹当个故事看。

我出这个文章的初心是觉得现在网上学习一门语言的教程大多都是从入门到精通这种,如果纯看视频,需要耗费很长的时间。其实在已经学习过一门语言的情况下,学习另一门语言应该是很快的事情。我希望做到的就是让有其他语言基础、希望快速学习一门新的语言的人,在看完我的教程之后能比较快的了解到node这门语言的特性,学习路线和一些可以跳过的坑。经验的东西会比知识多一些。

当然如果你和我有相同的经历或者有转node的想法,希望这篇文章对你有些借鉴意义。

一些感受

首先说一下我对这门语言的直观感受。node给我的感觉最大的就是:发展很快,但是学习资料很少,不太适合没有学过其他语言的,完全新手的人学习。其次,node跟其他语言的比较起来也挺尴尬的。跟python相比,似乎node有的特性python都有,速度上应该也比他快不了多少。跟传统的JAVA写的服务来说又不及他稳定。可能最大的优点就是他是用javaScript来编程,对于前端来说可以无缝衔接过来,所以学习的成本比较低。而且,现阶段node的岗位需求量还是挺大的,至少我感觉阿里系一直在招node前端,所以如果深度学习了node的话,至少不愁找不到工作。

在刚刚接触这门语言的时候,你能感觉到和java最大的不同就是:学java的时候你程序出问题了报异常,你把异常信息在百度上一查就能查到,但node现在还做不到,出了问题有的时候就得自己摸索,社区方面还没有java那么完善。

在学习的过程中我也翻阅了一些和node有关的书籍,感觉在时间上都比较滞后,这种滞后是相对与node的发展过于迅猛来说的,即便有一些新的内容的也不及官网翻阅的方便。

综上,直接学习node会遇到各种各样的问题,这也是我写这个帖子的初心,就是想把自己学习中遇到的问题与一些心得体会分享出来。如果你只学习过JAVA,不妨也接触一下这一门函数式编程的语言。

建议

如果你想快速上手这门语言,我给你的建议是:

1、快速学习一下javaScript的一些语法。  一开始没有必要接触的概念(坑)有:原型链。js也支持class写了,一开始就去了解原型链性价比太低。

2、学习koa并简单做个东西。

3、深入学习一下egg这个框架。

我的理由很简单,koa这个框架很简单,核心代码就几百行,很快就能上手。而egg这个框架是中国人开发出来的,文档资料也都是中文,甚至你哪些地方不明白都能以中文的形式询问到开发人员。

书籍、教程

很多人会选择在刚接触一项新的技术的时候观看教学视频来快速上手。但我觉得,学生时代你可以这么做,工作的时候真不一定有那么多的时间,如果可以学会以书籍、教程的方式进行学习,在时间上是要比看视频高出不少的。最重要的一点就是,书籍与教程无论是在实体书还是在网站上,他都比视频更容易复用,当你忘记的时候可以更方便进行查阅。

so,先推荐基本必看的

1、javaScript入门

2、ES6入门 (Es和js概念差不多,基本上可以说es就是js。)

以上两本书介绍的是javaScript的语法。第一本书比较基础。第二本书说的是这门语言的一些新特性,其中promise、async 和await最为关键。要知道,node是运行环境,编程时使用的语言是javaScript。

3、Node.js 创建第一个应用 | 菜鸟教程

菜鸟教程这么有名,就不用过多介绍了,学编程应该没有没用过的。

4、node官网

5、如果你要买一些书《JavaScript精髓》、朴灵的《Node深入浅出》。

你可以先用半天/一两天时间过一遍javaScript入门,然后再来看以下部分。

开始胡诌

先介绍一下node:

Node.js是基于Chrome JavaScript运行时建立的一个平台, 采用事件驱动和非阻塞I/O模型。

在node出现之前,我们写的javaScript代码都是运行在浏览器的javaScript解析器上。后来有一个叫 Ryan Dahl的外国人,他希望用高级语言来写高性能web服务。而高性能web服务的有两个东西是必须的( 非阻塞IO、事件驱动),他发现javaScript正好符合这两个个特点,而且在javaScript中,IO只能写成异步调用的(这对Ryan Dahl来说是个有点),所以他选择了javaScript。同时,他把Chrome浏览器中运行javaScript的部分迁移出来(v8引擎),使普通环境下也可运行javaScript,他就相当与java的虚拟机,有了他,我们就可以在编写完代码之后,直接命令行node wenjian.js运行,不同于java的是,node程序不会说编译成一个.class文件再来执行,他每一次都是动态编译。

第一个问题: 为什么选择Node

这个问题的另一面是:node适合什么样的业务。

结论是:node适合IO密集型的应用。请注意,IO不单单是指操作硬盘,实际中网络传输、硬件获取信息都可以抽象成IO。

传统的apache服务器在应对网络请求的时候,都是一个请求对应一个线程或者一个有效请求对应一个线程。在当请求中包含了对磁盘的操作的时候,应用需要解决数据之间的锁问题、要对线程进行生成、上下文切换等一系列操作。这这起中花费的时间不说,cpu在调用数据的时候是阻塞的状态,所以他会一直等这个数据回来,这就造成了cpu的等待、空转。在这里面,使用户的响应变慢的瓶颈不在cpu,而在与IO。

使用node的话,由于他是单线程,所以没有线程切换、锁的问题。其次他是非阻塞IO,调用了IO操作之后不要求数据直接就能返回,cpu直接就开始处理下一个操作,等到了IO操作结束之后,IO操作会去通知cpu执行接下来的操作。这就使计算机的IO处理速度大大提升。

第二个问题: Node怎么实现这个异步过程

这里只做代码层面上的分析。

首先,什么是异步?举个例子就是:cpu向硬盘请求一个数据,他发送了一个请求之后就自己干自己的东西去了,等硬盘查找到了数据之后,会通知cpu进行接下来的处理。

这里涉及两个东西,硬盘找到东西之后,处理什么?怎么处理?

处理什么:硬盘中找到的数据。

怎么处理:cpu一开始就得把硬盘查找结束后要执行的代码一并发给硬盘,告诉他,你找完了数据,带着这个函数,一起回来找我继续处理。

这就是一个异步过程。

写个伪代码,比如说我要cpu发送去硬盘查找一个数据,找完之后输出出来

// 同步letres=getData(位置x);输出res;//异步functionprint(data){输出data}getData(位置x,print)//注意 这里的print是一个函数

这里运行了getData这个函数之后,cpu就会跟硬盘说“去位置x的地方给我找个数据,找到了之后,带着数据(data),和后面要执行的函数(print),一起返回来找我继续处理”。

硬盘就开始查找了,过了一段时间(这个时间不确定),硬盘找到了数据,假设是b,硬盘就会过来告诉cpu说,诶,执行一下print(b)。最后,b就被输出到了屏幕上。

从这个例子中就可以看出,要想能够实现这种异步编程,有一个必要的条件就是,函数可以作为参数传递。而javaScript原生就支持这种特性。

javaScript可以进行函数式编程,简单来说,函数是一个普通对象,可以作为参数传递,也可作为返回值返回。学习函数式编程对我的冲击还是不小的,比如说现在可以这么写一段代码。

functionfunc1(func,arg){returnfunc(arg);}functionfunc2(arg){console.log(arg);}func1(func2,3);//输出3

刚开始接触的人应该都会这样的疑惑,这个函数不是脱裤子放屁吗。

但是,正因为有了这种写法,我们可以在return func(arg)前加上一些处理逻辑。这时候代码就变成了。

functionfunc1(func,arg){//func1的逻辑returnfunc(arg);}

上述中func称为func1的回调函数。

回调函数,就是将函数作为参数传入另一个函数中,等他办完了自己的事情再回头来调用。

举一个别人举过的例子:约会结束后你送你女朋友回家,离别时,你肯定会说:“到家了给我发条信息,我很担心你。” 其实这就是一个回调的过程。你留了个参数函数(要求女朋友给你发条信息)给你女朋友,然后你女朋友回家,回家的动作是主函数。她必须先回到家以后,主函数执行完了,再执行传进去的函数,然后你就收到一条信息了。

带来的问题

回头看看这个回调函数的写法,就可以发现其实他在语义上实在是非常反人类的。举个跟上面类似的例子。比如我现在要写一个函数,他要先执行一个mysql的操作(IO操作),然后再将结果输出

function printResult(sqlStr) {    

    connection.query(sqlStr,print);//看到这个print会不会觉得很莫名其妙。

}

function print(err,result) {   

    console.log(result);

}

printResult('select * from user'); //输出[Object object]

上面的connection.query是一个操作数据库的方法,他的参数就是(sql,callback,fields)callback就是回调函数的意思,而query方法会把这个回调函数的参数的第一参数识别为err,第二个参数识别为result。我们设计这个print的时候也要根据这个设计。

假设我们瞎设计这个print,写成这样,那就没有办法进行正常输出。

function printResult(sqlStr) {

    connection.query(sqlStr,print);

}

function print(result) {

    console.log(result);

}

printResult('select * from user'); //输出null  因为没有异常

回调函数使用和阅读的过程中一个很大的问题就是函数与函数之间的关联比较大,不好理解。这还只是一层回调函数,如果我想经过一些判断再进行这个查询和printResult。

function fun1(printResult,bol) { //懒得起名字

    if(bol){

        printResult('select *from user');

    } else {

        printResult('select *from manager');

    }

}

你看,传统的异步函数的写法就是这个回调函数,他的一个极大的问题就是要经过层层的回调来实现它的“通知”的功能,当逻辑变得复杂,这里面的层数也会不断加深。

现在,一个比较好的解决方案就是async和await。根据ES6电子书中的介绍,我们可以这么写我们的代码。

async printResult(sqlStr) {

    const [rows] = await promisePool.query(sqlStr);

        console.log(rows);

        return 1;

}

async func(){

    const res = await printResult('select * from user');

}

这里的写法和上面最大的区别就在于,直观上我现在直接就从数据库获取了数据之后就可以进行输出了,而不用再写成回调。

async 和await的一个简单解释就是,可以把耗时操作写进async函数中,而在async函数中如果要获取另一个async函数的返回值,就可以用await来获取(如上面的rows和res)。

这样就将异步的回调写法转换成为直观的同步写法了,而且它还可以享受到异步的速度。需要指出的是,async和await是通过Promise来实现的,Promise这个工具可以解决一些回调问题,而async更多的是强调异步问题。可以用async写的都可以用Promise来写,反之则不行,具体可以看看上面推荐的Es6的电子书。

注意

请注意,虽然这种方法将异步转化为了同步,但是他内部还是使用这种回调,每当有异步请求,内部一定是通过参数层层往下走,执行完了再层层往上的,这一点决定了node中网络编程和其他同步语言的不同。在阅读网上的各种博客的时候,心里要想清楚这是回调的写法还是async的写法还是Promise的写法,并且他们之间是可以穿插使用的。

我想,这就是node最基础的东西。有了这些,几乎就可以开始写代码了。

后记

第一次尝试输出自己的知识,可能很多地方做得不太好,我也在积极地寻找问题在哪里。后续会持续地发一些我觉得有价值的东西,有感兴趣的朋友可以和我交流交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • node.js组成:ECMAScript+Node模块API 安装:https://nodejs.org/en/→...
    Yans19阅读 136评论 0 0
  • 第三方模块(由多个文件组成,又称为包); 存在形式:①JS:提供实现项目具体功能的API接口;②以命令形式存在,辅...
    Yans19阅读 143评论 0 0
  • 以前有遇到一些服务端客户端交互问题,有时希望交互是异步的,服务器的响应是非即时的,但是http协议显然不符合我的需...
    冯行洲阅读 272评论 0 0
  • 哈希表 哈希表,又叫散列表,是数据结构的一种。散列表用途很广泛,比如一个电话薄,每一个姓名对应一个电话号码。姓名与...
    多云转晴i阅读 148评论 0 0
  • 进程与线程day 13.5 学习计划: 学完day13的任务 学会续行 保存代码 学习内容: 多进程还是多线程:优...
    眠森然阅读 141评论 0 0