HTTP是一種協議,計算機要共同聽從這種規則,才能相互通訊。html
瀏覽器打開一個網站,http走過的環節node
4.1寬帶運營商服務器查看自己緩存-》npm
4.2運營商服務器發起一個迭代DNS解析的請求(根域->頂級域->域名註冊商(IP地址)) 編程
4.3運營商服務器把結果返回給操做系統內核同時緩存起來 後端
4.4操做系統內核把結果返回給瀏覽器 數組
HTTP的組成:瀏覽器
http請求方法: 緩存
狀態碼:服務器端返回瀏覽器,告知瀏覽器請求成功或失敗的信息 服務器
回調試異步編程時的基礎,將後續邏輯封裝成起始函數的參數,逐層嵌套多線程
function learn(something){ console.log(something) } function we(callback, something){ something += 'is cool' callback(something) } //傳入具名函數 we(learn, 'Nodejs') //傳入匿名函數 we(function(something){ console.log(something) }, 'Jade')
同步:發送方發送數據後,等待接收方發回響應之後才發下一個數據包的通信方式
異步:發送方發出數據後,不等接收方發回響應,接着發送下個數據包的通信方式
磁盤的寫入(in)磁盤的讀取(out)
一次只能執行一個程序叫作單線程 一次能執行多個程序叫作多線程
阻塞:前一個程序未執行完就得一直等待
非阻塞:前一個程序未執行完時能夠掛起,繼續執行其餘程序,等到使用時再執行
一個觸發動做(例如點擊按鈕)
一個觸發動做引發的操做(例如點擊按鈕後彈出一個對話框)
function clickIt(e){ window.alert('Button is clicked') } var button = document.getElementById('#button') button.addEventListener('click', clickIt)
爲了某個事件註冊了回調函數,可是這個回調函數不是立刻執行,只有當事件發生的時候,纔會調用回掉函數,這種函數執行的方式叫作事件驅動~這種註冊回調就是基於事件驅動的回調,若是這些回調和異步I/O(數據寫入、讀取)操做相關,能夠看做是基於回調的異步I/O。只不過這種回調在nodejs中是有事件來驅動的
事件循環Eventloop,假若有大量的異步操做,一些I/O的耗時操做,甚至是一些定時器控制的延時操做,它們完成的時候都要調用相應的回調函數,而從完成一些密集的任務,而又不會阻塞整個程序執行的流程,此時須要一種機制來管理,這種機制叫作事件循環 總而言之,管理大量異步操做的機制叫作事件循環
EventLoop: 回調函數隊列,異步執行的函數會被壓入這個隊列;隊列被循環查詢。
與調用函數,訪問變量的能力有關。
做用域分爲:局部和全局(在局部做用域裏能夠訪問到全局做用域的變量,但在局部做用域外面就訪問不到局部做用域裏面所設定的變量)
//定義一個全局變量 var globalVariable = 'This is global variable' //定義一個全局做用域 function globalFunction(){ //在全局做用域裏定義一個局部變量 var localVariable = 'This is local variable' //打印出全局變量和局部變量 console.log('Visit global/loacal variable') console.log(globalVariable) console.log(localVariable) //改變全局變量 globalVariable = 'This is changed variable' //打印已經改變的全局變量 console.log(globalVariable) //在全局做用域裏定義一個局部函數 function localFunction(){ //在局部做用域裏定義一個局部變量 var innerLocalVariable = 'This is inner local variable' //打印全局變量,局部變量,內部局部變量 console.log('Visit global/local/innerLocal variable') console.log(globalVariable) console.log(localVariable) console.log(innerLocalVariable) } localFunction() } globalFunction() //輸出結果 //Visit global/loacal variable //This is global variable //This is local variable //This is changed variable //Visit global/local/innerLocal variable //This is changed variable //This is local variable //This is inner local variable
與this關鍵字有關,是調用當前可執行的代碼的引用,this老是指向調用這個方法的對象
js裏的this一般是當前函數的擁有者 this是js的一個關鍵字,表明函數運行時自動生成的一個內部對象,只能在函數內部使用
var pet ={ words: '...', speak: function(){ console.log(this.words)// '...' console.log(this == pet)//true } } //speak()方法裏的this指向擁有speak()方法的對象pet, //因此 this == pet 爲true pet.speak()
function pet(words){ this.words = words; console.log(this.words) // '...' console.log(this === gloabal)//true } pet('...')
function Pet(words){ this.words = words this.speak = function(){ console.log(this.words) //Miao console.log(this)//打印出this指向的整個實例化對象,{words: 'Miao',speak: [Function]} } } var cat = new Pet('Miao') cat.speak() //speak()裏面的this指向cat
三、更改上下文方法
(更改this指向的內容,可方便地實現繼承):
二者的做用徹底相同,只是接收參數的方式不太同樣
都是爲了改變某個函數運行時的context即上下文而存在的,換句話說,就是爲了改變函數內部this的指向。
var Pet = { words: '...0', speak: function(say){ console.log(say+ ' ' +this.words) } } pet.speak('Speak') //Speak ... var dog = { words: 'Wang' } pet.speak.call(dog, 'Speak') // Speak Wang //call()將pet.speak指定的原來的對象pet轉換爲指向對象dog
call()和apply()實現繼承
function Pet(words){ this.words = words this.speak = function(){ console.log(this.words) } } function Dog(words){ Pet.call(this,words) //直接把this轉化爲指向Dog對象,實現了Dog繼承了Pet } var dog = new Dog('Wang') dog.speak() //Wang
慕課網Nodejs基礎入門課程標題爬蟲
var http = require('http') var cheerio = require('cheerio') //將cheerio模塊require進來 /*添加cheerio模塊,就像jQuery同樣操做裝載後的html, 先安裝該模塊,在cmd命令行中輸入:npm install cheerio -g */ var url = 'http://www.imooc.com/learn/348' //找到課程頁面,只爬單頁面 function filterChapters(html){ var $ = cheerio.load(html) //經過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() var videos = chapter.find('.video').children('li') //每一章就是一個對象自變量 var chapterData = { chapterTitle : chapterTitle, videos: [ ] //該videos如今仍是一個空數組 } //對每個videos進行遍歷,拿到單個video videos.each(function(item){ var video = $(this).find('.J-media-item') var videoTitle = video.text() var id = video.attr('href').split('/video')[1]//split()方法是將指定字符串按某指定的分隔符進行拆分,拆將會造成一個字符串的數組並返回 chapterData.videos.push({ //將videoTitle和idpush進videos[ ]中 title: videoTitle, id : id }) }) courseData.push(chapterData) //將chapterData數組push進courseData中 }) return courseData //返回回去courseData給filterChapters } function printCourseInfo(courseData){ courseData.forEach(function(item){//由於courseData是一個數組,因此須要遍歷該數組後打開 var chapterTitle = item.chapterTitle console.log(chapterTitle+ '\n') //將chapterTitle打印出來 item.videos.forEach(function(video){ console.log(' 【' +video.id +' 】' + video.title +'\n') //遍歷videos後將其打印出來 }) }) } http.get(url, function(res){ //第一個參數傳入url,第二個參數是回調的方法 var html = ' ' res.on('data', function(data){ //response由data觸發的時候,回調data,把html的內容被拼加進來 html += data }) res.on('end', function(){ //數據累加,最後輸出 var courseData = filterChapters(html) //將html做爲參數傳遞給filterChapters,讓該函數去作數據的過濾 printCourseInfo(courseData) //經過printCourseInfo函數打印 }) }).on('error', function(){ //拋出異常,當出現錯誤的時候 console.log('獲取課程數據出錯!') })
其中,在安裝cheerio模塊時出現了錯誤,緣由是沒有全局變量安裝,使用 nmp install cheerio-g
或,選擇配置環境變量解決!
var EventEmitter = require('events').EventEmitter;
var instance = new EventEmitter();
instance.on('eventName',function(){});
//自定義最大數
每一個setMaxListeners針對的是一個特定事件,設置最大的num
instance.setMaxListeners(num)
instance.emit('eventName',arguments)
boolean.instance.emit('eventName',arguments) //true or false
instance.moveListener('eventName',funcName)//移除事件須要具名函數,匿名函數不可移除
instance.removeAllListener()//表示移除全部時間的監聽
instance.moveAllListener('eventName')//移除特定的event的全部事件
var EventEmitter = require('events').EventEmitter //注意是events! var life = new EventEmitter() //生成實例 life.setMaxListeners(11) function water(which){ console.log('The'+which+'is showing...') } life.on('date', water) //爲該實例添加監聽 life.on('date', function(which){ console.log('The'+which+'is down...') }) life.on('date', function(which){ console.log('The'+which+'is funny...') }) life.on('date', function(which){ console.log('The'+which+'is cool...') }) life.on('date', function(which){ console.log('The'+which+'is dark...') }) life.on('date', function(which){ console.log('The'+which+'is light...') }) life.on('date', function(which){ console.log('The'+which+'is wonderful...') }) life.on('date', function(which){ console.log('The'+which+'is interesting...') }) life.on('date', function(which){ console.log('The'+which+'is sad...') }) life.on('date', function(which){ console.log('The'+which+'is happy...') }) life.on('date', function(which){ console.log('The'+which+'is boring...') }) /*//判斷事件是否有被監聽過? var hasFirstListener = life.emit('date','movies') var hasSecondListener = life.emit('date1','dinner') var hasThirdListener = life.emit('date2','shopping') console.log(hasFirstListener) console.log(hasSecondListener) console.log(hasThirdListener)*/ //事件超過十個,出現警告。可設置setMaxListener life.on('date1',function(which){ console.log('The'+which+'dilicious') }) life.on('date1',function(which){ console.log('The'+which+'bad') }) //移除監聽事件時,只能移除具名函數 life.removeListener('date',water) //移除全部的監聽事件 life.removeAllListeners('date1')//須要傳入具體事件名稱纔不會所有刪除致使出錯 var hasFirstListener = life.emit('date','movies') var hasSecondListener = life.emit('date1','dinner') //查看監聽事件的個數 console.log(life.listeners('date').length) //移除掉一個後只剩10個 console.log(EventEmitter.listenerCount(life,'date'))