Node基礎(chǔ)

什么是Nodejs

  • Nodejs是c++編寫的呢铆,采用Chrome瀏覽器V8引擎哈恰,本質(zhì)上是JavaScript運(yùn)行環(huán)境
  • 可以解析JS代碼(沒有瀏覽器安全級(jí)限制)
  • 提供系統(tǒng)級(jí)別的API
    • 文件的讀寫
    • 進(jìn)程的管理
    • 網(wǎng)路通信

Node模塊分類

  • 核心模塊 http fs path
  • 文件模塊 var util = require('./util.js')
  • 第三方模塊var promise =require('bluebird')(通過npm install)

模塊的流程

  • 創(chuàng)建模塊 teacher.js
  • 導(dǎo)出模塊 exports.add = function(){}
  • 加載模塊 var teacher = require('./teacher.js')
  • 使用模塊 teacher.add('May')

Node.js API

  • url網(wǎng)址解析
    • url.parse('xxxxxx')
      • protocol:http/https
      • port:端口號(hào)
      • host:主機(jī)
      • hostname:主機(jī)名
      • hash:哈希#
      • search:查詢塘慕?
      • path
      • pathname
      • href
    • url.parse('xxxx',true) 使用querystring
    • url.format({})//和parse反向操作
    • url.resolve()//生產(chǎn)合法url鏈接地址
  • querystring
    • querystring.stringify({name:'scott',course:['jade','node'],from:''})
      =>'name=scott&course=jade&course=node&from='
    • querystring.stringify({name:'scott',course:['jade','node'],from:''},',')
      =>'name=scott,course=jade,course=node,from='
    • querystring.stringify({name:'scott',course:['jade','node'],from:''},',',':')
      =>'name:scott,course:jade,course:node,from:'
    • querystring.parse('name=scott&course=jade&course=node&from=')
      => { name: 'scott', course: [ 'jade', 'node' ], from: '' }
    • querystring.parse('name=scott,course=jade,course=node,from=',',')
    • querystring.parse('name:scott,course:jade,course:node,from:',',',':')
    • querystring.escape('xxx') // 轉(zhuǎn)義
    • querystring.unescape('xxxxx') //反轉(zhuǎn)義

HTTP知識(shí)

  • http請(qǐng)求過程

    1. http客戶端發(fā)起請(qǐng)求荞怒,創(chuàng)建端口
    2. http服務(wù)器在端口監(jiān)聽客戶端請(qǐng)求
    3. http服務(wù)器向客戶端返回狀態(tài)和內(nèi)容
  • 瀏覽器做了哪些操作

    1. chrome搜做自身DNS緩存(chrome://net-internals/#dns
    2. 如果瀏覽器沒有找到緩存或者緩存已失效轴或,chrome會(huì)搜索操作系統(tǒng)自身的DNS緩存
    3. 讀取本地的HOST文件
    4. 瀏覽器發(fā)起一個(gè)DNS的一個(gè)系統(tǒng)調(diào)用
    • 寬帶運(yùn)營(yíng)商服務(wù)器查看本身緩存
    • 運(yùn)營(yíng)商服務(wù)器發(fā)一個(gè)迭代DNS解析的請(qǐng)求瓦戚,運(yùn)營(yíng)商服務(wù)器把結(jié)果返回操作系統(tǒng)內(nèi)核同時(shí)緩存起來;操作系統(tǒng)內(nèi)核把結(jié)果返回瀏覽器摸吠;最終瀏覽器拿到了www.imooc.com對(duì)應(yīng)的ip地址
    1. 瀏覽器獲得域名對(duì)應(yīng)的IP地址后,發(fā)起HTTP"三次握手"
    2. TCP/IP連接建立起來后嚎花,瀏覽器就可以向服務(wù)器發(fā)送HTTP請(qǐng)求了
    3. 服務(wù)器端接收到了這個(gè)請(qǐng)求寸痢,根據(jù)路徑參數(shù),經(jīng)過后端的一些處理之后紊选,把處理后的一個(gè)結(jié)果的數(shù)據(jù)返回給瀏覽器
    4. 瀏覽器進(jìn)行解析和渲染
  • http結(jié)構(gòu)組成
    無論是請(qǐng)求和響應(yīng)啼止,都由HTTP頭和正文組成

    • HTTP頭:發(fā)送一些附加信息,如內(nèi)容類型兵罢,服務(wù)器發(fā)送相應(yīng)的日期献烦,HTTP狀態(tài)碼等
    • 正文:用戶提交的表單數(shù)據(jù)或者返回的數(shù)據(jù)
  • http請(qǐng)求方法

    • get:用于獲取或者讀取數(shù)據(jù)
    • post:向指定的資源提交數(shù)據(jù)
  • http狀態(tài)碼

    • 1xx 代表請(qǐng)求已經(jīng)接收了,正在處理
    • 2xx 表示請(qǐng)求已經(jīng)接收卖词,并且處理了
    • 3xx 表示重定向巩那,表示請(qǐng)求的時(shí)候需要更進(jìn)一步的重定向頁(yè)面
    • 4xx 表示請(qǐng)求有錯(cuò)誤,請(qǐng)求有語法錯(cuò)誤,請(qǐng)求無法實(shí)現(xiàn)
    • 5xx 表示服務(wù)器端的錯(cuò)誤,服務(wù)器端接收到請(qǐng)求但是處理出現(xiàn)問題

    常見請(qǐng)求碼

    • 200: 客戶端請(qǐng)求成功优妙;
    • 400:客戶端請(qǐng)求有語法錯(cuò)誤哩俭;
    • 401:請(qǐng)求沒經(jīng)過授權(quán);
    • 403:服務(wù)器收到請(qǐng)求窿春,但拒絕提供服務(wù),可能是沒有權(quán)限等等;
    • 404:資源沒找到页藻;
    • 500:服務(wù)器端錯(cuò)誤;
    • 503:服務(wù)器端當(dāng)下還不能處理客戶端這個(gè)請(qǐng)求植兰,過段時(shí)間恢復(fù)正常份帐。
  • node中的http模塊

    1. 什么是回調(diào)

      將后續(xù)邏輯封裝在函數(shù)回調(diào)中作為起始函數(shù)的參數(shù),逐層去嵌套,通過這種方式讓函數(shù)按照我們所期望的方式走完整個(gè)流程
    2. 什么是異步和同步

      同步是程序執(zhí)行一個(gè)任務(wù)楣导,后一個(gè)任務(wù)等待前一個(gè)任務(wù)完成后再執(zhí)行弥鹦,同步的執(zhí)行順序和任務(wù)的排列順序是一致的

      異步任務(wù)的排列順序和執(zhí)行順序無關(guān),程序執(zhí)行完成后是執(zhí)行回調(diào)函數(shù),常見異步函數(shù)setTimeOut和setInterval
    3. 什么是阻塞和非阻塞

      阻塞是當(dāng)你打電話問個(gè)請(qǐng)求時(shí)彬坏,那邊說你等等我給你查查朦促,這時(shí)候你電話仍然是掛起的,等待等待栓始,直到拿到結(jié)果务冕。
      非阻塞是打電話過去問,然后掛電話幻赚,等那邊找到結(jié)果或打電話給你禀忆,你該干嘛就干嘛。在node.js里面單線程可以通過回調(diào)函數(shù)來做異步操作落恼,達(dá)到非阻塞的效果箩退。
    4. 什么是單線程和多線程

      單線程:只有執(zhí)行上一個(gè)任務(wù)完成后,下一個(gè)才能執(zhí)行佳谦。優(yōu)點(diǎn)是安全戴涝。

      多線程:同時(shí)執(zhí)行多個(gè)函數(shù),缺點(diǎn)是容易爭(zhēng)搶資源钻蔑,有管理和分配資源的難度啥刻。
    5. 什么是事件和事件驅(qū)動(dòng)

      nodeJs中客戶端連接到服務(wù)器端時(shí)會(huì)觸發(fā)事件。打開文件也會(huì)觸發(fā)事件等咪笑,所有能夠觸發(fā)事件的都是EventEmitter下的實(shí)例可帽;先注冊(cè)事件,等事件被觸發(fā)的時(shí)候窗怒,才執(zhí)行事件回調(diào)映跟。這種形式就是事件驅(qū)動(dòng)。
    6. 什么是事件循環(huán)

      EventLoop是事件管理機(jī)制扬虚,當(dāng)存在很多異步操作申窘、IO操作時(shí),會(huì)被壓入EventLoop隊(duì)列孔轴,有個(gè)單線程不斷查詢隊(duì)列中是否有事件
  • HTTP性能小測(cè)試

使用Apache ab
ab -n1000 -c10 https:www.imooc.com/
// -n 1000 總請(qǐng)求數(shù)是1000個(gè)
// -c10 并發(fā)數(shù)為10 
/**
 * 一個(gè)初級(jí)爬蟲Demo
 */
var https = require('https');
var cheerio = require('cheerio');
var url = 'https://www.imooc.com/learn/348';


// 請(qǐng)求url地址,獲取頁(yè)面html
https.get(url,function (res) {
    var html = '';
    res.on('data',function(data){
        html += data;
    });
    res.on('end',function () {
        var courseData = filterCharpter(html);
        printChapter(courseData);
    });
    res.on('error',function () {
        console.log('系統(tǒng)異常');
    })
})

// 獲取頁(yè)面章節(jié)的函數(shù)
function filterCharpter (html) {
    var $ = cheerio.load(html);
    var chapters =$('.chapter');
    var courseData = [];
    chapters.each(function (value) {
        var chapter = $(this);
        var chapterTitle = chapter.find('strong').text().trim().split('\n')[0];
        var videos = chapter.find('.video').children('li');
        chapter = {
            chapterTitle : chapterTitle,
            videos:[]
        }
        videos.each(function(val){
            var video = $(this).find('a').text().trim();
            var videoName = video.split('\n')[0];
            var videoTime = video.split('\n')[1].trim();
            chapter.videos.push({name:videoName,time:videoTime});

        });
        courseData.push(chapter);
    });
   return courseData;
}
// 格式化打印頁(yè)面
function printChapter (courseData) {
    courseData.forEach(function (val) {
        var chapterTitle = val.chapterTitle;
        console.log('章節(jié)標(biāo)題:'+chapterTitle+'\n');
        val.videos.forEach(function (value) {
            console.log('  '+value.name+'時(shí)長(zhǎng):'+value.time+'\n');
        })
    })
}

promise

針對(duì)異步場(chǎng)景的解決方案

  • Promise對(duì)象三種狀態(tài)

    • 未完成(pending)
    • 已完成(fulfilled/resolved)
    • 失斕攴ā(rejected)
    • 只能從pending->resolved或者pending->rejected
  • then方法

    promise可以保證then的順序

    then方法返回promise對(duì)象,兩個(gè)參數(shù)分別是成功回調(diào)函數(shù)和失敗回調(diào)函數(shù)路鹰。

promiseObj.then(onResolved,onRejected);
onResolved = function(value){
    return promiseObj2;//返回一個(gè)promise對(duì)象
}
onRejected = function(err){}
  • 基于promise的進(jìn)階版爬蟲(一次爬取多個(gè)文件)
var https = require('https');
var cheerio = require('cheerio');

var baseUrl = 'https://www.imooc.com/learn/'
var videosArray = [728,637,348,259,197,134,75];
videosArray = videosArray.map(item => baseUrl+item);
// 創(chuàng)建promise
function getPageAsync(url){
    return new Promise(function(resolve,rejecte){
        // 請(qǐng)求url地址,獲取頁(yè)面html
        https.get(url,function (res) {
            var html = '';
            res.on('data',function(data){
                html += data;
            });
            res.on('end',function () {
                resolve(html);
            });
            res.on('error',function (error) {
                rejecte(error);
            })
        })
    })
}

// 獲取頁(yè)面章節(jié)的函數(shù)
function filterCharpter (html) {
    var $ = cheerio.load(html);
    var title  = $('.course-infos h2').text().trim();
    var page = {
        title:title,
        courseData:[]
    }
    var chapters =$('.chapter');
    var courseData = [];
    chapters.each(function (value) {
        var chapter = $(this);
        var chapterTitle = chapter.find('strong').text().trim().split('\n')[0];
        var videos = chapter.find('.video').children('li');
        chapter = {
            chapterTitle : chapterTitle,
            videos:[]
        }
        videos.each(function(val){
            var video = $(this).find('a').text().trim();
            var videoName = video.split('\n')[0];
            var videoTime = video.split('\n')[1].trim();
            chapter.videos.push({name:videoName,time:videoTime});

        });
        courseData.push(chapter);
    });
    page.courseData = courseData;
    return page;
}

// 打印章節(jié)內(nèi)容
function printCourseData (coursesData) {
    coursesData.forEach(function(item){
        console.log('課程名:'+item.title+'\n');
        item.courseData.forEach(function(val){
            var chapterTitle = val.chapterTitle;
            console.log('   '+chapterTitle+'\n');
            val.videos.forEach(function (value) {
                console.log('      '+value.name+'時(shí)長(zhǎng):'+value.time+'\n');
            })
        })
        console.log('\n');
    })
}
// 所有頁(yè)面的promise數(shù)組
var pagesPromiseArray = [];
videosArray.forEach(function(val){
    pagesPromiseArray.push(getPageAsync(val));
})

//promise.all方法
Promise
    .all(pagesPromiseArray)
    .then(function (pages) {
        var coursesData = [];
        pages.forEach(function(html){
            var courses = filterCharpter(html)
            coursesData.push(courses)
        })
        printCourseData(coursesData);
    })
    .catch (function (e) {
        console.log('程序異常');
    })

Node API

  • Buffer 處理TCP/圖形/文件/網(wǎng)絡(luò)

    • buffer[index]
    • buffer.length
    • buffer.write(string,[offset,length,encoding])
    var buf = new Buffer('Hello World');
    buf.length//11
    buf.write('Hi World');
    buf.toString()//'Hi Worldrld' 初始化時(shí)長(zhǎng)度被指定贷洲,不會(huì)清空后面內(nèi)容
    buf.write(' Dingsusu lalala',2,16)
    buf.toString()//'Hi Dingsusu'
    
    • buffer.copy(target[,targetStart,sourceStart,sourceEnd])
  • Stream 流,用來暫存和移動(dòng)數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晋柱,一起剝皮案震驚了整個(gè)濱河市优构,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雁竞,老刑警劉巖钦椭,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拧额,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡彪腔,警方通過查閱死者的電腦和手機(jī)侥锦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來德挣,“玉大人恭垦,你說我怎么就攤上這事「裥幔” “怎么了番挺?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)屯掖。 經(jīng)常有香客問我玄柏,道長(zhǎng),這世上最難降的妖魔是什么贴铜? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任粪摘,我火速辦了婚禮,結(jié)果婚禮上阀湿,老公的妹妹穿的比我還像新娘赶熟。我一直安慰自己瑰妄,他們只是感情好陷嘴,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著间坐,像睡著了一般灾挨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竹宋,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天劳澄,我揣著相機(jī)與錄音,去河邊找鬼蜈七。 笑死秒拔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的飒硅。 我是一名探鬼主播砂缩,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼三娩!你這毒婦竟也來了庵芭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤雀监,失蹤者是張志新(化名)和其女友劉穎双吆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡好乐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年匾竿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曹宴。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搂橙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笛坦,到底是詐尸還是另有隱情区转,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布版扩,位于F島的核電站废离,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏礁芦。R本人自食惡果不足惜蜻韭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柿扣。 院中可真熱鬧肖方,春花似錦、人聲如沸未状。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)司草。三九已至艰垂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埋虹,已是汗流浹背猜憎。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搔课,地道東北人胰柑。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像爬泥,于是被迫代替她去往敵國(guó)和親柬讨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1急灭、url網(wǎng)址解析 url.parse(url姐浮,true,true)將url解析成json對(duì)象第二個(gè)參數(shù)true可...
    飛飛廉閱讀 114評(píng)論 0 0
  • 這幾天在學(xué)習(xí)node葬馋,以下的筆記主要是自己看《Node.js開發(fā)指南》的筆記卖鲤,下面的內(nèi)容主要是1到4章的 單線程肾扰、...
    Gopal閱讀 378評(píng)論 0 0
  • 共14+1個(gè)小點(diǎn) 最后一個(gè)點(diǎn)是socket 很簡(jiǎn)單 概念: //并行是指兩個(gè)或者多個(gè)事件在同一時(shí)刻發(fā)生;而并發(fā)是指...
    貝灬小暉閱讀 221評(píng)論 0 1
  • 初看Node 最新版的官方文檔 看到Http模塊的類以及http模塊的屬性和方法等蛋逾,有點(diǎn)發(fā)懵的感覺集晚,結(jié)合...
    Node101閱讀 526評(píng)論 0 0
  • 用小妹的話來形容回家的這一周:全身上下彌漫著濃濃的鄉(xiāng)土氣息。時(shí)光飛逝区匣,轉(zhuǎn)眼一周就這樣結(jié)束了偷拔。 還好,留下了很多美好...
    恩煦閱讀 304評(píng)論 2 0