课程地址:

进击Node.js基础(一)

进击Node.js基础(二)

1. nodejs创建服务器

  1. var http = require('http'); //加载http模块
  2.  
  3. //请求进来时, 告诉服务器做什么, 于是给createServer传递一个匿名回调函数.
  4. //两个参数, 前面是请求体, 后面是响应体. 请求体用来获取请求相应信息,比如请求ip地址,请求的类型get/post,res用来返回响应
  5. http.createServer(function(req, res) {
  6. res.writeHead(200, {'Content-Type': 'text/palin'});
  7. res.end('Hello World\n');
  8. }).listen(1337, '127.0.0.1'); //通过listen使服务器在1337端口监听请求
  9. console.log('Server running at https://127.0.0.1:1337/');

2. nodejs安装:

一开始直接使用sudo apt-get install node后, 安装好的node不能启动且node -v也没有输出. node.js的版本号是v0.10.25.但是用npm安装一些包时候却说node版本不够, 没搞明白node和nodejs区别在哪里.

于是卸载掉从nodejs.org上下了新版, 是node v6.10.0. 解压后, 直接在那个目录下可以启动node, 在网上查了使用了一个链接, 分别把node 和 npm设置了全局:

  1. sudo ln -s /media/hao/3b6b3418-c087-4836-a75d-6d7a6023e495/Programs/node-v6.10.0-linux-x64/bin/node /usr/sbin/node
  2. sudo ln -s /media/hao/3b6b3418-c087-4836-a75d-6d7a6023e495/Programs/node-v6.10.0-linux-x64/bin/npm /usr/sbin/npm

可以用了.

关于nodejs和node版本的区别,参考这个帖子吧: nodejs各版本的区别

3. 模块: 从这里开始都是慕课网老师Scott进击NodeJS基础(一)(二)课程的笔记

  • 创建模块

    1. teacher.js
  • 导出模块
    1. exports.add = function(){ }
  • 加载模块
    1. var teacher = require('./teacher.js')
  • 使用模块
    1. teacher.add('Scott')

  

4. nodejs中一些api

  1. url:
    1. url.parse
    2. url.format:
    3. url.resolve

  2. querystring

  

5. 用nodejs做的一个爬虫:

  1. var http = require('http')
  2. var cheerio = require('cheerio') //npm install cheerio
  3. var url = 'http://www.imooc.com/learn/348'
  4.  
  5. function filterChapters(html){
  6. var $ = cheerio.load(html)
  7. var chapters = $('.chapter')
  8. // [{
  9. // chapterTitle: '',
  10. // videos: [
  11. // title:'',
  12. // id: ''
  13. // ]
  14. // }]
  15. var courseData = []
  16. chapters.each(function(item){
  17. var chapter = $(this)
  18. var chapterTitle = chapter.find('strong').text().trim('\n').split('\n')[0]
  19. var videos = chapter.find('.video').children('li')
  20. var chapterData = {
  21. chapterTitle: chapterTitle,
  22. videos: []
  23. }
  24. videos.each(function(item){
  25. var video = $(this).find(".J-media-item")
  26. var videoTitle = video.text().split(/\s+/).slice(1,-2).join(' ')
  27. var id = video.attr('href').split('video/')[1]
  28. chapterData.videos.push({
  29. title: videoTitle,
  30. id: id
  31. })
  32. })
  33. courseData.push(chapterData)
  34. })
  35. return courseData
  36. }
  37.  
  38. function printCourseInfo(courseData){
  39. courseData.forEach(function(item){
  40. var chapterTitle = item.chapterTitle
  41. console.log(chapterTitle + '\n')
  42.  
  43. item.videos.forEach(function(video){
  44. console.log(' [' + video.id + ']' + video.title + '\n')
  45. })
  46. })
  47. }
  48. http.get(url, function(res) {
  49. var html = ''
  50.  
  51. res.on('data', function(data){
  52. html += data
  53. })
  54.  
  55. res.on('end', function(){
  56. var courseData = filterChapters(html)
  57. printCourseInfo(courseData)
  58. })
  59. }).on('error', function(){
  60. console.log('获取课程数据错误')
  61. })

6. 事件监听的一个小例子

  1. var EventEmitter = require('events').EventEmitter
  2. var life = new EventEmitter()
  3.  
  4. //addEventListener
  5.  
  6. life.setMaxListeners(6) //设置事件最大监听数 默认为10. 超出这个数目会报警告
  7.  
  8. life.on('求安慰', function(who){
  9. console.log('给 ' + who + ' 倒水')
  10. })
  11.  
  12. life.on('求安慰', function(who){
  13. console.log('给 ' + who + ' ...1')
  14. })
  15.  
  16. life.on('求安慰', function(who){
  17. console.log('给 ' + who + ' ...2')
  18. })
  19.  
  20. life.on('求安慰', function(who){
  21. console.log('给 ' + who + ' ...3')
  22. })
  23.  
  24. life.on('求安慰', function(who){
  25. console.log('给 ' + who + ' ...4')
  26. })
  27.  
  28. life.on('求安慰', function(who){
  29. console.log('给 ' + who + ' ...5')
  30. })
  31.  
  32. life.on('求安慰', function(who){
  33. console.log('给 ' + who + ' ...6')
  34. })
  35.  
  36. var hasBeenListener = life.emit('求安慰', '杠子') //会返回值, 看是否被监听过
  37.  
  38. //要移除函数, 不能够使用匿名函数, 只能移除具名函数
  39.  
  40. console.log(life.listeners('求安慰').length) //查询监听事件数
  41. console.log(EventEmitter.listenerCount(life, '求安慰'))
  42.  
  43. life.removeAllListeners('求安慰')
  44. life.emit('求安慰','gangzi')

7. Promise.js  imooc

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Promise animation</title>
  5. <style type="text/css">
  6. .ball{
  7. width: 40px;
  8. height: 40px;
  9. border-radius: 20px;
  10. }
  11. .ball1 { background: red;}
  12. .ball2 { background: yellow;}
  13. .ball3 { background: green;}
  14. </style>
  15. <script type="text/javascript" src="/home/hao/node_modules/bluebird/js/browser/bluebird.js"></script>
  16. </head>
  17.  
  18. <body>
  19. <div class="ball ball1" style="margin-left: 0;"></div>
  20. <div class="ball ball2" style="margin-left: 0;"></div>
  21. <div class="ball ball3" style="margin-left: 0;"></div>
  22.  
  23. </body>
  24. <script type="text/javascript">
  25. var ball1 = document.querySelector('.ball1')
  26. var ball2 = document.querySelector('.ball2')
  27. var ball3 = document.querySelector('.ball3')
  28.  
  29. function animate(ball, distance, cb){
  30. setTimeout(function(){
  31. var marginLeft = parseInt(ball.style.marginLeft, 10)
  32. if(marginLeft === distance){
  33. cb && cb()
  34. }
  35. else {
  36. if(marginLeft < distance){
  37. marginLeft++
  38. } else {
  39. marginLeft--
  40. }
  41. ball.style.marginLeft = marginLeft + 'px'
  42. animate(ball,distance,cb)
  43. }
  44. },13);
  45. }
  46. // animate(ball1, 100, function(){
  47. // animate(ball2, 200, function() {
  48. // animate(ball3, 300, function(){
  49. // animate(ball3, 150, function(){
  50. // animate(ball2, 150, function(){
  51. // animate(ball1, 150, function(){
  52.  
  53. // })
  54. // })
  55. // })
  56. // })
  57. // })
  58. // })
  59. var Promise = window.Promise
  60. function promiseAnimate(ball, distance){
  61. return new Promise(function(resolve, reject){
  62. function _animate(){
  63. setTimeout(function(){
  64. var marginLeft = parseInt(ball.style.marginLeft, 10)
  65. if(marginLeft === distance){
  66. resolve()
  67. }
  68. else {
  69. if(marginLeft < distance){
  70. marginLeft++
  71. } else {
  72. marginLeft--
  73. }
  74. ball.style.marginLeft = marginLeft + 'px'
  75. _animate()
  76. }
  77. },13);
  78. }
  79. _animate()
  80. })
  81.  
  82. }
  83. promiseAnimate(ball1, 100)
  84. .then(function() {
  85. return promiseAnimate(ball2,200)
  86. }).then(function(){
  87. return promiseAnimate(ball3,300)
  88. }).then(function(){
  89. return promiseAnimate(ball3,150)
  90. }).then(function(){
  91. return promiseAnimate(ball2,150)
  92. }).then(function(){
  93. return promiseAnimate(ball1,150)
  94. })
  95. </script>
  96. </html>
  • Promise就是对象,有三种状态: 未完成(pending), 已完成(fulfilled), 失败(rejected). 过程不可逆
  • Promise A与A+不同点
    • A+规范通过术语thenable来区分promise对象
    • A+定义onFulfilled/onRejected必须是作为函数来调用, 而且调用过程必须是异步的
    • A+严格定义了then方法链式调用时onFulfilled/onRejected的调用顺序
  • 使用promise改进之前的爬虫代码:
    1. var http = require('http')
    2. var Promise = require('bluebird')
    3. var cheerio = require('cheerio') //npm install cheerio
    4. var baseUrl = 'http://www.imooc.com/learn/'
    5. var url = 'http://www.imooc.com/learn/348'
    6. var videoIds = [728,637,197,348,259,75,134]
    7.  
    8. function filterChapters(html){
    9. var $ = cheerio.load(html)
    10. var chapters = $('.chapter')
    11. var title = $('h2.l').text()
    12. var number = $($('span.meta-value.js-learn-num')).text()
    13.  
    14. // courseData = {
    15. // title: title,
    16. // number: number,
    17. // videos: [{
    18. // chapterTitle: '',
    19. // videos: [
    20. // title: '',
    21. // id: ''
    22. // ]
    23. // }]
    24. // }
    25. var courseData = {
    26. title: title,
    27. videos: [],
    28. number:number
    29. }
    30. chapters.each(function(item){
    31. var chapter = $(this)
    32. var chapterTitle = chapter.find('strong').text().trim('\n').split('\n')[0]
    33. var videos = chapter.find('.video').children('li')
    34. var chapterData = {
    35. chapterTitle: chapterTitle,
    36. videos: []
    37. }
    38. videos.each(function(item){
    39. var video = $(this).find(".J-media-item")
    40. var videoTitle = video.text().split(/\s+/).slice(1,-2).join(' ')
    41. var id = video.attr('href').split('video/')[1]
    42. chapterData.videos.push({
    43. title: videoTitle,
    44. id: id
    45. })
    46.  
    47. })
    48. courseData.videos.push(chapterData)
    49. })
    50. return courseData
    51. }
    52.  
    53. function printCourseInfo(coursesData){
    54. coursesData.forEach(function(courseData){
    55. // console.log(courseData.number + ' 人学过' + courseData.title + '\n')
    56. console.log('### ' + courseData.title + '\n')
    57. courseData.videos.forEach(function(item){
    58. console.log(item.chapterTitle);
    59. item.videos.forEach(function(video){
    60. console.log(' [' + video.id + ']' + video.title + '\n')
    61. })
    62.  
    63. })
    64. })
    65. // coursesData.forEach(function(item){
    66.  
    67. // })
    68. }
    69. function getPageAsync(url){
    70. return new Promise(function(resolve,reject){
    71. console.log('正在爬取 ' + url)
    72. http.get(url, function(res) {
    73. var html = ''
    74.  
    75. res.on('data', function(data){
    76. html += data
    77. })
    78.  
    79. res.on('end', function(){
    80. resolve(html)
    81. // var courseData = filterChapters(html)
    82. // printCourseInfo(courseData)
    83. })
    84. }).on('error', function(e){
    85. reject(e)
    86. console.log('获取课程数据错误')
    87. })
    88. })
    89.  
    90. }
    91.  
    92. var fetchCourseArray = []
    93.  
    94. videoIds.forEach(function(id){
    95. fetchCourseArray.push(getPageAsync(baseUrl + id))
    96. })
    97.  
    98. Promise
    99. .all(fetchCourseArray)
    100. .then(function(pages){
    101. var coursesData = []
    102. pages.forEach(function(html){
    103. var courses = filterChapters(html)
    104. coursesData.push(courses)
    105. })
    106.  
    107. coursesData.sort(function(a,b){
    108. return a.number < b.number
    109. })
    110. printCourseInfo(coursesData)
    111. })

  

8. Buffer API

使用Buffer来读写图片的一个例子:

  1. var fs = require('fs')
  2.  
  3. fs.readFile('logo.png', function(err, origin_buffer){
  4. console.log(Buffer.isBuffer(origin_buffer))
  5. fs.writeFile('logo_buffer.png', origin_buffer, function(err){
  6. if(err) console.log(err)
  7. })
  8.  
  9. // var base64Image = new Buffer(origin_buffer).toString('base64')
  10. var base64Image = origin_buffer.toString('base64')
  11.  
  12. console.log(base64Image)
  13.  
  14. var decodedImage = new Buffer(base64Image, 'base64')
  15.  
  16. console.log(Buffer.compare(origin_buffer, decodedImage))
  17.  
  18. fs.writeFile('logo_decodes.png', decodedImage, function(err){
  19. if(err) console.log(err)
  20. })
  21. })

9. Stream API

  1. //拷贝文件
  2. var fs = require('fs')
  3. var source = fs.readFileSync('../buffer/logo.png')
  4.  
  5. fs.writeFileSync('stream_copy_logo.png', source)
  1. //拷贝图片
  2. var fs = require('fs')
  3.  
  4. var readStream = fs.createReadStream('stream_copy_logo.js')
  5. var n = 0
  6.  
  7. readStream
  8. .on('data', function(chunk) {
  9. n++
  10. console.log('data emits')
  11. console.log(Buffer.isBuffer(chunk)) //true
  12. // console.log(chunk.toString('utf8')) //要读的文件的内容
  13.  
  14. readStream.pause()
  15. console.log('data pause')
  16. setTimeout(function(){
  17. console.log('data pause end')
  18. readStream.resume()
  19. }, 3000)
  20. })
  21. .on('readable', function(){
  22. console.log('data readable')
  23. })
  24. .on('end', function() {
  25. console.log(n)
  26. console.log('data ends')
  27. })
  28. .on('close', function() {
  29. console.log('data close')
  30. })
  31. .on('error', function(e){
  32. console.log('data read error' + e)
  33. })
  1. //拷贝视频
  2. var fs = require('fs')
  3.  
  4. var readStream = fs.createReadStream('1.mp4')
  5. var writeStream = fs.createWriteStream('1-stream.mp4')
  6.  
  7. readStream.on('data', function(chunk){
  8. //如果缓存区数据还在写, 那么暂停读数据
  9. if( writeStream.write(chunk) === false){
  10. console.log('still cached')
  11. readStream.pause()
  12. }
  13. })
  14.  
  15. readStream.on('end', function(){
  16. writeStream.end()
  17. })
  18.  
  19. writeStream.on('drain', function() {
  20. console.log('data drains')
  21.  
  22. readStream.resume()
  23. })

10. 流与pipe

网络请求与pipe:

  1. var http = require('http')
  2. var fs = require('fs')
  3. var request = require('request')
  4.  
  5. http
  6. .createServer(function(req, res) {
  7. //=====================常规做法
  8. // fs.readFile('./buffer/logo.png', function(err, data){
  9. // if(err){
  10. // res.end('file not exist!')
  11. // } else {
  12. // res.writeHeader(200, {'Context-Type' : 'text/html'})
  13. // res.end(data)
  14. // }
  15. // })
  16.  
  17. //===============使用pipe方法读取本地图片
  18. // fs.createReadStream('../buffer/logo.png').pipe(res)
  19.  
  20. //从网络上获取一张图片 在不保存的前提下再返回给浏览器
  21. request('http://www.imooc.com/static/img/index/logo.png?t=1.1').pipe(res)
  22. //pipe会自动监听data和end事件. 可自动控制流量压力
  23. })
  24. .listen(8090)

使用pipe重构上面的copy视频的代码:

  1. var fs = require('fs')
  2. fs.createReadStream('1.mp4').pipe(fs.createWriteStream('1-pipe.mp4'))

总结:

  1. 可读流是为了读取外部数据, 并把数据缓存到内部的buffer数组
  2. 可写流是为了消费数据, 从可读流里获取数据然后对得到的chunk数据库进行处理.
    1. var Readable = require('stream').Readable
    2. var Writable = require('stream').Writable
    3.  
    4. var readStream = new Readable()
    5. var writeStream = new Writable()
    6.  
    7. readStream.push('I ')
    8. readStream.push('Love ')
    9. readStream.push('Imooc\n ')
    10. readStream.push(null)
    11.  
    12. writeStream._write = function(chunk, encode, cb) {
    13. console.log(chunk.toString())
    14. cb()
    15. }
    16.  
    17. readStream.pipe(writeStream)

  

一个自己定制的读写转换流的实现:

  1. var stream = require('stream')
  2. var util = require('util')
  3.  
  4. function ReadStream(){
  5. stream.Readable.call(this)
  6.  
  7. }
  8.  
  9. util.inherits(ReadStream, stream.Readable)
  10.  
  11. ReadStream.prototype._read = function(){
  12. this.push('I ')
  13. this.push('Love ')
  14. this.push('Imooc\n ')
  15. this.push(null)
  16. }
  17.  
  18. function WriteStream(){
  19. stream.Writable.call(this)
  20. this._cached = new Buffer('')
  21. }
  22.  
  23. util.inherits(WriteStream, stream.Writable)
  24.  
  25. WriteStream.prototype._write = function(chunk, encode, cb){
  26. console.log(chunk.toString())
  27. cb()
  28. }
  29.  
  30. function TransformStream(){
  31. stream.Transform.call(this)
  32. }
  33.  
  34. util.inherits(TransformStream, stream.Transform)
  35.  
  36. TransformStream.prototype._transform = function(chunk, encode, cb){
  37. this.push(chunk)
  38. cb()
  39. }
  40.  
  41. TransformStream.prototype._flush = function(cb){
  42. this.push('Oh Yeah!')
  43. cb()
  44. }
  45.  
  46. var rs = new ReadStream()
  47. var ws = new WriteStream()
  48. var ts = new TransformStream()
  49.  
  50. rs.pipe(ts).pipe(ws)

nodejs学习(imooc课程笔记, 主讲人Scott)的更多相关文章

  1. Deeplearning.ai课程笔记--汇总

    从接触机器学习就了解到Andrew Ng的机器学习课程,后来发现又出来深度学习课程,就开始在网易云课堂上学习deeplearning.ai的课程,Andrew 的课真是的把深入浅出.当然学习这些课程还 ...

  2. Nodejs学习笔记(三)——一张图看懂Nodejs建站

    前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...

  3. Nodejs学习笔记(四)——支持Mongodb

    前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...

  4. vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结

    vue—你必须知道的   目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...

  5. Nodejs学习笔记(二)——Eclipse中运行调试Nodejs

    前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...

  6. NodeJS学习笔记之Connect中间件模块(一)

    NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...

  7. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  8. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  9. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

随机推荐

  1. Makefile 中@是什么意思

    http://bbs.chinaunix.net/thread-1916415-1-1.html linux源码的顶级Makefile中有这么一句 $(filter-out _all sub-make ...

  2. CSS-弹性布局-伪类选择器-复杂选择器

    1.定位 1.堆叠顺序 一旦将元素变为已定位元素的话,元素们则有可能出现堆叠的效果. 如何改变堆叠顺序? 属性:z-index 取值:无单位的数字,数字越大越靠上. 注意: 1.父子元素间,z-ind ...

  3. Django的学习(五)————实战问题

    一.多参数问题: 首先是在添加一个新的参数,其次在url中把这个id传递过去 def article_page(request, article_id): article = models.Artic ...

  4. 如何将mysql卸载干净

    一.在控制面板中卸载mysql软件 二.卸载过后删除C:\Program Files (x86)\MySQL该目录下剩余了所有文件,把mysql文件夹也删了 三.windows+R运行“regedit ...

  5. s4-9 二层设备

    二层(数据链路层)设备有哪些?  网卡  网桥  交换机 NIC 网卡  Nework Interface Card  为主机提供介质的访问.  MAC地址烧在网卡的 ROM中 NIC 网 ...

  6. form表单序列化为json格式数据

    在web开发过程中,经常遇到将form序列化不能格式的字符串提交到后台,下面就介绍怎样将form表单序列化为json字符串. 首先,是扩展的jquery序列化插件,依赖jquery.经测试,这段代码可 ...

  7. OOP中的六种关系以及和JDK或框架中源码进行匹配对应

    前言:这六种关系里:泛化=实现>组合>聚合>关联>依赖:其中组合-聚合-关联这三个如果只是给出一段代码是无法判断具体是什么关系的,需要配合语义或说业务场景来能进行区分(和设计模 ...

  8. 微信小程序之下拉加载和上拉刷新

    微信小程序下拉加载和上拉刷新两种实现方法 方法一:onPullDownRefresh和onReachBottom方法实现小程序下拉加载和上拉刷新 首先要在json文件里设置window属性       ...

  9. BT1120时序,可以用于自测用

    module bt1120_gen #( , , , , , )( input clk, input rst_p, // input [5:0] h_sync_pixcels, // input [5 ...

  10. [好文分享]MySQL 加锁处理分析

    原文转自:http://hedengcheng.com/?p=771 背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经 ...