javascript
NodeJS必知基础知识(非巨详细)
Node.js是啥?
node.js是構建在Chrome v8 引擎上的一個javascript 運行環(huán)境
node和Chrome一樣都是基于事件驅動的異步架構!Chrome是基于事件的交互,而node是基于事件的I/O;
node沒有HTML、Webkit和顯卡驅動等UI技術支持;
文件引入
如果當前文件夾下有index.js和2.js
2.js 里包含變量a(let a=1)
node在執(zhí)行時會把代碼重新編譯,編譯時會把代碼打包成字符串放入一個函數(shù)里進行編譯,所以直接在全局var 或者let聲明的變量并不能通過全局直接調(diào)用!
模塊
//02.js module.exports=function(){console.log("666") }; //被覆蓋 module.exports=123123123; //為模塊賦值 // module.exports.num=123; //可以為模塊定義屬性 //index.js const obj=require("./2.js"); //如果不加./ 則在核心模塊或第三方依賴模塊里找,就不再當前文件夾下找了 console.log(obj); //123123123重新定向
//2.js exports=module.exports exprots.fn=function(){}; //對exports重新定向,并添加新的屬性fn,方便index.js的require訪問;node把所有抽象成了事件,node執(zhí)行時,同步異步差異如下:
// 同步 process.nextTick(()=>{ console.log("1") //2 }) process.nextTick(()=>{console.log("2") //3 }) //異步 setImmediate(()=>{console.log("3") //6process.nextTick(()=>{console.log("4")//8} }) setImmediate(()=>{console.log("5") //7 }) setTimeout(function(){console.log("8") //5 },0) //同步 process.nextTick(()=>{console.log("7") //4 }) console.log("6") //1node 輸出結果 6 1 2 7 8 3 5 4
事件隊列,自動排隊
macro-task:script(全部代碼) (setInterval setTimeout定時器,同優(yōu)先級誰先注冊誰高) setImmediate I/O
micro-task:process.nextTick Promise=>then
同步的是整體代碼,而異步之所以異步是將參數(shù)里的回調(diào)函數(shù)在將來執(zhí)行
node執(zhí)行初期執(zhí)行一個無線循環(huán)
while(true){
1.scipt(全部代碼),產(chǎn)生同步異步;
2.執(zhí)行完script后 將micro-task 隊列里的事件全部執(zhí)行;
3.再次執(zhí)行macro-task 隊列里的第二層script,產(chǎn)生第二層的micro-task的
4.緊接著執(zhí)行micro-task里新產(chǎn)生的事件隊列
一直到最里層的macro-task代碼產(chǎn)生的micro-task隊列執(zhí)行完畢…
}
第一次循環(huán):
macro-task:script(第一層代碼,檢查到有l(wèi)og 4 ) setTimeout=>3
micro-task:process.nextTick=>2 Promise=>then 1
第二次循環(huán):
macro-task:{script(第一層代碼,檢查到有l(wèi)og 4 )}->第一次已執(zhí)行 setTimeout=>3->第二次正在執(zhí)行
micro-task:{process.nextTick=>2 Promise=>then 1}->第一次已執(zhí)行
mode輸出結果 4 2 1 3
總結優(yōu)先級,可以簡單看為:
nextTick > Promise.then > setTimeout > setImmediate
下載包
npm.nodejs.com–>sort by keywords search
運行使用nodejs
實現(xiàn)在控制臺進入當前文件夾,node + 文件名 回車執(zhí)行
- 初始化項目信息
- 安裝模塊
- 添加上傳使用用戶
或者去官網(wǎng)npm.nodejs.com 注冊
//登錄npm login Username: Password: Email://上傳 npm publish //上傳當前初始化的node環(huán)境里的文件,同時會對比以前的文件- 如果國外服務器卡頓,使用淘寶鏡像
node原生模塊
- 事件模塊 events
如:
const eventEmitter=require("events").EventEmitter; const myEmitter=new EventEmitter();//這里有一個異步 setTimeout(()=>{//異步的結果出來 },2000);myEmitter.on("someEvents",()=>{console.log("這個某個異步的回調(diào)執(zhí)行函數(shù)") }或者:
const eventEmitter=require("events").EventEmitter; const myEmitter=new EventEmitter(); const fn=()=>{console.log("這個某個異步的回調(diào)執(zhí)行函數(shù)") } //這里有一個異步 setTimeout(()=>{//異步的結果出來myEmitter.emit("fengyu") },2000); myEmitter.on("fengyu",fn}; //第一個參數(shù)是綁定的監(jiān)聽名號,第二個是回調(diào)函數(shù),異步結果執(zhí)行的函數(shù)- 自定義模塊的原型
- path模塊
URL模塊
- 導入URL模塊
查詢字符串querystring
const qs =require('querystring');const queryObj=qs.parse(myUrl.search.slice(1)) console.log(queryObj); // 通過. 使用里面的數(shù)據(jù)斷言 assert
用于判斷得到的值是否為期望值
const assert = require('assert'); //assert(布爾值,報錯信息) assert(true,"如果第一個參數(shù)的布爾值不為true,這個字符串就為報錯信息!") //或:assert(表達式,預期,報錯信息)加密模塊
const crypto = require('crypto');const KEY="fengyu"; const obj=crypto.createHash('md5');obj.update(KEY);const password=obj.digest('hex'); //輸出剛才的結果,1次 參數(shù)可以選擇進制位數(shù)等文件操作 js
const js = require('fs')fs.readFile('路徑',(err,data)=>{if(err) threw err;console.log(data); }); //有Sync 同步 沒有回調(diào), 沒有Sync 異步有回調(diào) ,錯誤對象err永遠是第一個參數(shù)位; //如果讀取錯誤,err是個json對象,不為null,包含路徑,結果,權限等鍵與值//輸出的data一般是個buffer數(shù)據(jù),如果添加第二個參數(shù)(進制編碼),可以將data轉換為其他文字編碼,如UTF-8 //異步讀取 const js = require('fs')const fn=async()=>{<!--await fs.readFile("./1.txt","utf8",fucntion(err,data){if(err)return;return data;} //取不到--> const data =await new Promise((resolve,reject)=>{fs.readFile("./1.txt","utf8",(err,data)=>{if(err) return reject(err)resolve(data)}}console.log(data); //取不到 } //同步讀取 const js = require('fs');const data=fs.readFileSync("./2.txt","utf8");//讀取錯誤立馬報錯 //寫 const js = require('fs'); const data="fengyu"; fs.writeFile("./2.txt",data,'utf8',err=>{if(err) throw err;console.log("寫入成功"); }) //utf8 編碼參數(shù)可選 //寫 const js = require('fs'); const data="fengyu";創(chuàng)建服務器實例
const http=require('http') const fs=require('fs') const server=http.createServer((req,res)=>{res.writeHead(200,{"Content-Type:"text/plain;charset=utf-8""}); //響應頭,text/plain 是純文本,charset設置文字編碼res.write("向客戶端返回數(shù)據(jù)"); //數(shù)據(jù)響應,返回值res.end()l//結束響應 }); //req requeset, res response //修改后打斷^C,重新執(zhí)行, 或者安裝 npm全局安裝nodemon server.listen(3000); //建議監(jiān)聽1024以上//返回頁面if(req.method==="GET"){res.writeHead(200,{"Content-Type":"text/html;charset=utf-8"})switch(req.url){case "/":res.write(fs.redFileSync("index.html","utf8"));<!--fs.readFile("index.html","utf8",(err,data)=>{res.write(data)res.end();//由于是異步的,fs的readFirefile執(zhí)行在后面的end后,需要把end提到這里面主動提前執(zhí)行end}--><!--如果使用管道流fs.createReadStream("index.html").pipe(res);-->}} const http=require('http') const server=http.createServer((req,res)=>{const obj={a:1,b:2}res.write(JSON.stringfy(obj) }) server.listen(3000,()=>{console.log("服務器監(jiān)聽在localhost:3000") })框架 Koa
cosnt Koa= require('koa')const app =new Koa//中間件 理論上可以注冊任意多個 洋蔥模型 app.use(async(ctx,next)=>{await next();//提交到下一層 });//ctx context 上下文環(huán)境- 路由管理
RESTfull規(guī)則
npm安裝koa-static 管理靜態(tài)資源
Pug模板引擎
需要 koa pug koa-views(視圖管理)
const Koa=require('koa') const views=require('koa-views')const {join}=require('path') // 使用join鏈接 //pug不需要實例,可以自動識別const app=new Koaapp.use(views(join(__dirname,"views"),{extension:'pug' //模板pug,views是文件夾名,路徑下有個views文件夾 })) //一定要在其他中間件之前注冊模板信息app.use(async(ctx)=>{ctx.render("index.pug") //渲染模板 })app.listen(3000)MongoDB
- 安裝
一路默認即可,路徑最好在根目錄,確認安裝環(huán)境,如果沒有要添加到系統(tǒng)的環(huán)境變量里
- 啟動服務:mongod --dbpath Desktop/demo/db 啟動服務并初始化目錄,完成時會提示連接的監(jiān)聽端口,默認是27017(關閉窗口會斷開連接)
- 客戶端連接:mongo
- 查看數(shù)據(jù)庫集合:show dbs
- 創(chuàng)建數(shù)據(jù)庫:use DATABASE_NAME
- 查看正在使用的集合:db
概念: 庫database,集合collection
//use 就創(chuàng)建了數(shù)據(jù)庫,并進入當前數(shù)據(jù)庫 > use test //dropDatabase 刪除當前數(shù)據(jù)庫 switched to db test //createCollection創(chuàng)建集合 > db.createCollection("runoob") { "ok" : 1 } > show collections runoob //添加數(shù)據(jù) > db.runoob.insert({"name" : "fengyu","length":"10"}) //db.runoob.drop()刪除集合 //find不加參數(shù)查找當前目標集合的所有數(shù)據(jù),可以傳參,內(nèi)容為數(shù)據(jù)里的信息 > db.runoob.find()//find({"name":"fengyu"})- 其他主機連接服務器數(shù)據(jù)庫
總結
以上是生活随笔為你收集整理的NodeJS必知基础知识(非巨详细)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模拟模型学习----几何布朗运动模拟
- 下一篇: 异星工厂服务器无响应,异星工厂无法联机解