nodejs学习(imooc课程笔记, 主讲人Scott)
课程地址:
1. nodejs创建服务器
- var http = require('http'); //加载http模块
- //请求进来时, 告诉服务器做什么, 于是给createServer传递一个匿名回调函数.
- //两个参数, 前面是请求体, 后面是响应体. 请求体用来获取请求相应信息,比如请求ip地址,请求的类型get/post,res用来返回响应
- http.createServer(function(req, res) {
- res.writeHead(200, {'Content-Type': 'text/palin'});
- res.end('Hello World\n');
- }).listen(1337, '127.0.0.1'); //通过listen使服务器在1337端口监听请求
- 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设置了全局:
- sudo ln -s /media/hao/3b6b3418-c087-4836-a75d-6d7a6023e495/Programs/node-v6.10.0-linux-x64/bin/node /usr/sbin/node
- 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基础(一)(二)课程的笔记
- 创建模块
- teacher.js
- 导出模块
- exports.add = function(){ }
- 加载模块
- var teacher = require('./teacher.js')
- 使用模块
- teacher.add('Scott')
4. nodejs中一些api
- url:
- url.parse
- url.format:
url.resolve
- url.parse
querystring
- var http = require('http')
- var cheerio = require('cheerio') //npm install cheerio
- var url = 'http://www.imooc.com/learn/348'
- function filterChapters(html){
- var $ = cheerio.load(html)
- var chapters = $('.chapter')
- // [{
- // chapterTitle: '',
- // videos: [
- // title:'',
- // id: ''
- // ]
- // }]
- var courseData = []
- chapters.each(function(item){
- var chapter = $(this)
- var chapterTitle = chapter.find('strong').text().trim('\n').split('\n')[0]
- var videos = chapter.find('.video').children('li')
- var chapterData = {
- chapterTitle: chapterTitle,
- videos: []
- }
- videos.each(function(item){
- var video = $(this).find(".J-media-item")
- var videoTitle = video.text().split(/\s+/).slice(1,-2).join(' ')
- var id = video.attr('href').split('video/')[1]
- chapterData.videos.push({
- title: videoTitle,
- id: id
- })
- })
- courseData.push(chapterData)
- })
- return courseData
- }
- function printCourseInfo(courseData){
- courseData.forEach(function(item){
- var chapterTitle = item.chapterTitle
- console.log(chapterTitle + '\n')
- item.videos.forEach(function(video){
- console.log(' [' + video.id + ']' + video.title + '\n')
- })
- })
- }
- http.get(url, function(res) {
- var html = ''
- res.on('data', function(data){
- html += data
- })
- res.on('end', function(){
- var courseData = filterChapters(html)
- printCourseInfo(courseData)
- })
- }).on('error', function(){
- console.log('获取课程数据错误')
- })
6. 事件监听的一个小例子
- var EventEmitter = require('events').EventEmitter
- var life = new EventEmitter()
- //addEventListener
- life.setMaxListeners(6) //设置事件最大监听数 默认为10. 超出这个数目会报警告
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' 倒水')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...1')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...2')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...3')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...4')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...5')
- })
- life.on('求安慰', function(who){
- console.log('给 ' + who + ' ...6')
- })
- var hasBeenListener = life.emit('求安慰', '杠子') //会返回值, 看是否被监听过
- //要移除函数, 不能够使用匿名函数, 只能移除具名函数
- console.log(life.listeners('求安慰').length) //查询监听事件数
- console.log(EventEmitter.listenerCount(life, '求安慰'))
- life.removeAllListeners('求安慰')
- life.emit('求安慰','gangzi')
7. Promise.js imooc
- <!DOCTYPE html>
- <html>
- <head>
- <title>Promise animation</title>
- <style type="text/css">
- .ball{
- width: 40px;
- height: 40px;
- border-radius: 20px;
- }
- .ball1 { background: red;}
- .ball2 { background: yellow;}
- .ball3 { background: green;}
- </style>
- <script type="text/javascript" src="/home/hao/node_modules/bluebird/js/browser/bluebird.js"></script>
- </head>
- <body>
- <div class="ball ball1" style="margin-left: 0;"></div>
- <div class="ball ball2" style="margin-left: 0;"></div>
- <div class="ball ball3" style="margin-left: 0;"></div>
- </body>
- <script type="text/javascript">
- var ball1 = document.querySelector('.ball1')
- var ball2 = document.querySelector('.ball2')
- var ball3 = document.querySelector('.ball3')
- function animate(ball, distance, cb){
- setTimeout(function(){
- var marginLeft = parseInt(ball.style.marginLeft, 10)
- if(marginLeft === distance){
- cb && cb()
- }
- else {
- if(marginLeft < distance){
- marginLeft++
- } else {
- marginLeft--
- }
- ball.style.marginLeft = marginLeft + 'px'
- animate(ball,distance,cb)
- }
- },13);
- }
- // animate(ball1, 100, function(){
- // animate(ball2, 200, function() {
- // animate(ball3, 300, function(){
- // animate(ball3, 150, function(){
- // animate(ball2, 150, function(){
- // animate(ball1, 150, function(){
- // })
- // })
- // })
- // })
- // })
- // })
- var Promise = window.Promise
- function promiseAnimate(ball, distance){
- return new Promise(function(resolve, reject){
- function _animate(){
- setTimeout(function(){
- var marginLeft = parseInt(ball.style.marginLeft, 10)
- if(marginLeft === distance){
- resolve()
- }
- else {
- if(marginLeft < distance){
- marginLeft++
- } else {
- marginLeft--
- }
- ball.style.marginLeft = marginLeft + 'px'
- _animate()
- }
- },13);
- }
- _animate()
- })
- }
- promiseAnimate(ball1, 100)
- .then(function() {
- return promiseAnimate(ball2,200)
- }).then(function(){
- return promiseAnimate(ball3,300)
- }).then(function(){
- return promiseAnimate(ball3,150)
- }).then(function(){
- return promiseAnimate(ball2,150)
- }).then(function(){
- return promiseAnimate(ball1,150)
- })
- </script>
- </html>
- Promise就是对象,有三种状态: 未完成(pending), 已完成(fulfilled), 失败(rejected). 过程不可逆
- Promise A与A+不同点
- A+规范通过术语thenable来区分promise对象
- A+定义onFulfilled/onRejected必须是作为函数来调用, 而且调用过程必须是异步的
- A+严格定义了then方法链式调用时onFulfilled/onRejected的调用顺序
- 使用promise改进之前的爬虫代码:
- var http = require('http')
- var Promise = require('bluebird')
- var cheerio = require('cheerio') //npm install cheerio
- var baseUrl = 'http://www.imooc.com/learn/'
- var url = 'http://www.imooc.com/learn/348'
- var videoIds = [728,637,197,348,259,75,134]
- function filterChapters(html){
- var $ = cheerio.load(html)
- var chapters = $('.chapter')
- var title = $('h2.l').text()
- var number = $($('span.meta-value.js-learn-num')).text()
- // courseData = {
- // title: title,
- // number: number,
- // videos: [{
- // chapterTitle: '',
- // videos: [
- // title: '',
- // id: ''
- // ]
- // }]
- // }
- var courseData = {
- title: title,
- videos: [],
- number:number
- }
- chapters.each(function(item){
- var chapter = $(this)
- var chapterTitle = chapter.find('strong').text().trim('\n').split('\n')[0]
- var videos = chapter.find('.video').children('li')
- var chapterData = {
- chapterTitle: chapterTitle,
- videos: []
- }
- videos.each(function(item){
- var video = $(this).find(".J-media-item")
- var videoTitle = video.text().split(/\s+/).slice(1,-2).join(' ')
- var id = video.attr('href').split('video/')[1]
- chapterData.videos.push({
- title: videoTitle,
- id: id
- })
- })
- courseData.videos.push(chapterData)
- })
- return courseData
- }
- function printCourseInfo(coursesData){
- coursesData.forEach(function(courseData){
- // console.log(courseData.number + ' 人学过' + courseData.title + '\n')
- console.log('### ' + courseData.title + '\n')
- courseData.videos.forEach(function(item){
- console.log(item.chapterTitle);
- item.videos.forEach(function(video){
- console.log(' [' + video.id + ']' + video.title + '\n')
- })
- })
- })
- // coursesData.forEach(function(item){
- // })
- }
- function getPageAsync(url){
- return new Promise(function(resolve,reject){
- console.log('正在爬取 ' + url)
- http.get(url, function(res) {
- var html = ''
- res.on('data', function(data){
- html += data
- })
- res.on('end', function(){
- resolve(html)
- // var courseData = filterChapters(html)
- // printCourseInfo(courseData)
- })
- }).on('error', function(e){
- reject(e)
- console.log('获取课程数据错误')
- })
- })
- }
- var fetchCourseArray = []
- videoIds.forEach(function(id){
- fetchCourseArray.push(getPageAsync(baseUrl + id))
- })
- Promise
- .all(fetchCourseArray)
- .then(function(pages){
- var coursesData = []
- pages.forEach(function(html){
- var courses = filterChapters(html)
- coursesData.push(courses)
- })
- coursesData.sort(function(a,b){
- return a.number < b.number
- })
- printCourseInfo(coursesData)
- })
- var http = require('http')
8. Buffer API
使用Buffer来读写图片的一个例子:
- var fs = require('fs')
- fs.readFile('logo.png', function(err, origin_buffer){
- console.log(Buffer.isBuffer(origin_buffer))
- fs.writeFile('logo_buffer.png', origin_buffer, function(err){
- if(err) console.log(err)
- })
- // var base64Image = new Buffer(origin_buffer).toString('base64')
- var base64Image = origin_buffer.toString('base64')
- console.log(base64Image)
- var decodedImage = new Buffer(base64Image, 'base64')
- console.log(Buffer.compare(origin_buffer, decodedImage))
- fs.writeFile('logo_decodes.png', decodedImage, function(err){
- if(err) console.log(err)
- })
- })
9. Stream API
- //拷贝文件
- var fs = require('fs')
- var source = fs.readFileSync('../buffer/logo.png')
- fs.writeFileSync('stream_copy_logo.png', source)
- //拷贝图片
- var fs = require('fs')
- var readStream = fs.createReadStream('stream_copy_logo.js')
- var n = 0
- readStream
- .on('data', function(chunk) {
- n++
- console.log('data emits')
- console.log(Buffer.isBuffer(chunk)) //true
- // console.log(chunk.toString('utf8')) //要读的文件的内容
- readStream.pause()
- console.log('data pause')
- setTimeout(function(){
- console.log('data pause end')
- readStream.resume()
- }, 3000)
- })
- .on('readable', function(){
- console.log('data readable')
- })
- .on('end', function() {
- console.log(n)
- console.log('data ends')
- })
- .on('close', function() {
- console.log('data close')
- })
- .on('error', function(e){
- console.log('data read error' + e)
- })
- //拷贝视频
- var fs = require('fs')
- var readStream = fs.createReadStream('1.mp4')
- var writeStream = fs.createWriteStream('1-stream.mp4')
- readStream.on('data', function(chunk){
- //如果缓存区数据还在写, 那么暂停读数据
- if( writeStream.write(chunk) === false){
- console.log('still cached')
- readStream.pause()
- }
- })
- readStream.on('end', function(){
- writeStream.end()
- })
- writeStream.on('drain', function() {
- console.log('data drains')
- readStream.resume()
- })
10. 流与pipe
网络请求与pipe:
- var http = require('http')
- var fs = require('fs')
- var request = require('request')
- http
- .createServer(function(req, res) {
- //=====================常规做法
- // fs.readFile('./buffer/logo.png', function(err, data){
- // if(err){
- // res.end('file not exist!')
- // } else {
- // res.writeHeader(200, {'Context-Type' : 'text/html'})
- // res.end(data)
- // }
- // })
- //===============使用pipe方法读取本地图片
- // fs.createReadStream('../buffer/logo.png').pipe(res)
- //从网络上获取一张图片 在不保存的前提下再返回给浏览器
- request('http://www.imooc.com/static/img/index/logo.png?t=1.1').pipe(res)
- //pipe会自动监听data和end事件. 可自动控制流量压力
- })
- .listen(8090)
使用pipe重构上面的copy视频的代码:
- var fs = require('fs')
- fs.createReadStream('1.mp4').pipe(fs.createWriteStream('1-pipe.mp4'))
总结:
- 可读流是为了读取外部数据, 并把数据缓存到内部的buffer数组
- 可写流是为了消费数据, 从可读流里获取数据然后对得到的chunk数据库进行处理.
- var Readable = require('stream').Readable
- var Writable = require('stream').Writable
- var readStream = new Readable()
- var writeStream = new Writable()
- readStream.push('I ')
- readStream.push('Love ')
- readStream.push('Imooc\n ')
- readStream.push(null)
- writeStream._write = function(chunk, encode, cb) {
- console.log(chunk.toString())
- cb()
- }
- readStream.pipe(writeStream)
- var Readable = require('stream').Readable
一个自己定制的读写转换流的实现:
- var stream = require('stream')
- var util = require('util')
- function ReadStream(){
- stream.Readable.call(this)
- }
- util.inherits(ReadStream, stream.Readable)
- ReadStream.prototype._read = function(){
- this.push('I ')
- this.push('Love ')
- this.push('Imooc\n ')
- this.push(null)
- }
- function WriteStream(){
- stream.Writable.call(this)
- this._cached = new Buffer('')
- }
- util.inherits(WriteStream, stream.Writable)
- WriteStream.prototype._write = function(chunk, encode, cb){
- console.log(chunk.toString())
- cb()
- }
- function TransformStream(){
- stream.Transform.call(this)
- }
- util.inherits(TransformStream, stream.Transform)
- TransformStream.prototype._transform = function(chunk, encode, cb){
- this.push(chunk)
- cb()
- }
- TransformStream.prototype._flush = function(cb){
- this.push('Oh Yeah!')
- cb()
- }
- var rs = new ReadStream()
- var ws = new WriteStream()
- var ts = new TransformStream()
- rs.pipe(ts).pipe(ws)
nodejs学习(imooc课程笔记, 主讲人Scott)的更多相关文章
- Deeplearning.ai课程笔记--汇总
从接触机器学习就了解到Andrew Ng的机器学习课程,后来发现又出来深度学习课程,就开始在网易云课堂上学习deeplearning.ai的课程,Andrew 的课真是的把深入浅出.当然学习这些课程还 ...
- Nodejs学习笔记(三)——一张图看懂Nodejs建站
前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...
- Nodejs学习笔记(四)——支持Mongodb
前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...
- vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结
vue—你必须知道的 目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...
- Nodejs学习笔记(二)——Eclipse中运行调试Nodejs
前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...
- NodeJS学习笔记之Connect中间件模块(一)
NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...
- Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识
目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...
- Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例
目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...
- Nodejs学习笔记(十六)--- Pomelo介绍&入门
目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...
随机推荐
- Makefile 中@是什么意思
http://bbs.chinaunix.net/thread-1916415-1-1.html linux源码的顶级Makefile中有这么一句 $(filter-out _all sub-make ...
- CSS-弹性布局-伪类选择器-复杂选择器
1.定位 1.堆叠顺序 一旦将元素变为已定位元素的话,元素们则有可能出现堆叠的效果. 如何改变堆叠顺序? 属性:z-index 取值:无单位的数字,数字越大越靠上. 注意: 1.父子元素间,z-ind ...
- Django的学习(五)————实战问题
一.多参数问题: 首先是在添加一个新的参数,其次在url中把这个id传递过去 def article_page(request, article_id): article = models.Artic ...
- 如何将mysql卸载干净
一.在控制面板中卸载mysql软件 二.卸载过后删除C:\Program Files (x86)\MySQL该目录下剩余了所有文件,把mysql文件夹也删了 三.windows+R运行“regedit ...
- s4-9 二层设备
二层(数据链路层)设备有哪些? 网卡 网桥 交换机 NIC 网卡 Nework Interface Card 为主机提供介质的访问. MAC地址烧在网卡的 ROM中 NIC 网 ...
- form表单序列化为json格式数据
在web开发过程中,经常遇到将form序列化不能格式的字符串提交到后台,下面就介绍怎样将form表单序列化为json字符串. 首先,是扩展的jquery序列化插件,依赖jquery.经测试,这段代码可 ...
- OOP中的六种关系以及和JDK或框架中源码进行匹配对应
前言:这六种关系里:泛化=实现>组合>聚合>关联>依赖:其中组合-聚合-关联这三个如果只是给出一段代码是无法判断具体是什么关系的,需要配合语义或说业务场景来能进行区分(和设计模 ...
- 微信小程序之下拉加载和上拉刷新
微信小程序下拉加载和上拉刷新两种实现方法 方法一:onPullDownRefresh和onReachBottom方法实现小程序下拉加载和上拉刷新 首先要在json文件里设置window属性 ...
- BT1120时序,可以用于自测用
module bt1120_gen #( , , , , , )( input clk, input rst_p, // input [5:0] h_sync_pixcels, // input [5 ...
- [好文分享]MySQL 加锁处理分析
原文转自:http://hedengcheng.com/?p=771 背景 MySQL/InnoDB的加锁分析,一直是一个比较困难的话题.我在工作过程中,经常会有同事咨询这方面的问题.同时,微博上也经 ...