雜項 ----Node
1.node是什麼?
Node是一個基於chrome V8引擎的JavaScript程式碼執行環境
--瀏覽器(軟體)能夠執行Javascript程式碼,瀏覽器就是JavaScript程式碼的執行環境
--Node(軟體)能夠執行Javascript程式碼,Node就是JavaScript程式碼的執行環境
LTS =Long time support 長期支援穩定版,Current 擁有最新特性的實驗版
Node.js-------> ECMAscrip 和Node模組API組成,所以ECMAscript語法都能使用
2.Node.js的模組化開發
-Node.js規定一個JavaScript檔案就是一個模組,模組內部定義的變數和函式預設情況下在外部無法得到
-也可以使用module.exports,預設指向的是同一個地址,如果地址改變,最終結果以module.exports為準
·模組成員匯出----------------------->module.exports=匯出變數 匯入方需要用一個變數去得到他----> const 變數 = require('路徑')
// a.js // 在模組內部定義變數 let version = 1.0; // 在模組內部定義方法 const sayHi = name => `您好, ${name}`;// 向模組外部匯出資料 exports.version = version; exports.sayHi = sayHi;
·模組成員匯入
1 // b.js 2 // 在b.js模組中匯入模組a 3 let a = require('./b.js'); 4 // 輸出b模組中的version變數 5 console.log(a.version); 6 // 呼叫b模組中的sayHi方法 並輸出其返回值 7 console.log(a.sayHi('黑馬講師'));
3.相對路徑和絕對路徑
相對路徑是相對於node的不是所寫程式碼的,可以用__dirname獲得當前程式碼的所在路徑,而程式碼中的require方法中的相對路徑是相對於程式碼資料夾的所以可以直接寫相對路徑
4.第三方模組安裝
修改映象下載地址: 安裝nrm:npm install -g nrm 檢視地址:nrm ls 更改地址:nrm use **** -本地安裝 npm install(unstall) 模組名 -全域性安裝 npm install(unstall) 模組名 -g
模組:
1.nodemon,但檔案進行儲存操作時會自動執行該檔案,這樣就不用在修改檔案後重新自己執行,直接重新整理就能看到效果
2.nrm,修改通過npm下載的地址
3.Gulp,基於node平臺開發的前端構建工具,講機械化操作編寫成任務,但需要進行操作時執行一個命令就好了
·使用npm install gulp 下載 (不需要全域性安裝) ·在專案根目錄下建立gulpfile.js檔案 ·重構專案的資料夾結構src目錄放置原始碼檔案,dist目錄放置構建後的檔案 ·在gulpfile,js檔案中編寫任務 ·在命令列工具中執行gulp任務 Gulp中提供的方法,想要進行更多操作就要使用Gulp外掛(npm下載外掛,引用外掛,呼叫外掛) 1.gulp.src(): 獲取任務要處理的檔案 2.gulp.dest(): 輸出檔案 3.gulp.task(): 建立gulp任務 4.gulp.watch(): 監控檔案變化
·gulp外掛
gulp-htmlmin :html檔案壓縮 gulp-csso :壓縮css gulp-babel :JavaScript語法轉化 gulp-less: less語法轉化 gulp-uglify :壓縮混淆JavaScript gulp-file-include 公共檔案包含 browsersync 瀏覽器實時同步
4.node_modules資料夾的問題
1.資料夾以及檔案過多過碎,當我們將專案整體拷貝給別人的時候,,傳輸速度會很慢很慢.
2.複雜的模組依賴關係需要被記錄,確保模組的版本和當前保持一致,否則會導致當前專案執行報錯
--所以我們可以直接把package.json給別人
5.package.json
可以使用npm install 就可以把package.json所有模組安裝
package.json專案描述檔案,記錄了當前專案資訊,例如專案名稱、版本、作者、github地址、當前專案依賴了哪些第三方模組等。
使用npm init -y命令生成。
分為專案依賴(dependencies)和開發依賴(devDependencies)
作用:
鎖定包的版本,確保再次下載時不會因為包版本不同而產生問題
加快下載速度,因為該檔案中已經記錄了專案所依賴第三方包的樹狀結構和包的下載地址,重新安裝時只需下載即可,不需要做額外的工作
6.模組查詢規則
-當模組擁有路徑但沒有後綴時
--require('./find.js'); --require('./find'); 1.require方法根據模組路徑查詢模組,如果是完整路徑,直接引入模組。 2.如果模組字尾省略,先找同名JS檔案再找同名JS資料夾 3.如果找到了同名資料夾,找資料夾中的index.js 4.如果資料夾中沒有index.js就會去當前資料夾中的package.json檔案中查詢main選項中的入口檔案 5.如果找指定的入口檔案不存在或者沒有指定入口檔案就會報錯,模組沒有被找到
-模組查詢規則-當模組沒有路徑且沒有後綴時
--require('find'); 1.Node.js會假設它是系統模組 2.Node.js會去node_modules資料夾中 3.首先看是否有該名字的JS檔案 4.再看是否有該名字的資料夾 5.如果是資料夾看裡面是否有index.js 6.如果沒有index.js檢視該資料夾中的package.json中的main選項確定模組入口檔案 7.否則找不到報錯
Gulp不止提供了庫檔案還提供了命令列工具,這樣就可以通過命令列工具執行gulpfile.js下的任務了( gulp 任務名)
舊:
1 gulp.task('htmlmin',()=>{ 2 gulp.src('./src/*.html') 3 .pipe(fileinclude()) 4 // 壓縮html檔案中的程式碼 5 .pipe(htmlmin({ collapseWhitespace: true })) 6 .pipe(gulp.dest('dist/css/new css')); 7 8 }); 9 ERRO:[09:52:58] The following tasks did not complete: htmlmin 10 [09:52:58] Did you forget to signal async completion?
現在:
gulp.task('htmlmin',()=>{ return gulp.src('./src/*.html') .pipe(fileinclude()) // 壓縮html檔案中的程式碼 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('dist/css/new css')); });
OR
gulp.task('htmlmin',(cb)=>{ return gulp.src('./src/*.html') .pipe(fileinclude()) // 壓縮html檔案中的程式碼 .pipe(htmlmin({ collapseWhitespace: true })) .pipe(gulp.dest('dist/css/new css')); (cb); });
5.同步API和非同步API
1.同步API:只有當前API執行完成後,才能繼續執行下一個API
console.log('before');
console.log('after');
2.非同步API:當前API的執行不會阻塞後續程式碼的執行
console.log('before');
setTimeout(
() => { console.log('last');
}, 2000);
console.log('after');
區別:
1.·同步API可以從返回值拿到API執行的結果,但非同步API不可以
程式碼執行時先將同步程式碼執行再將非同步程式碼執行
// 同步 function sum (n1, n2) { return n1 + n2; } const result = sum (10, 20); // 非同步 function getMsg () { setTimeout(function () { return { msg: 'Hello Node.js' } }, 2000); } const msg = getMsg ();//undefind------------結果為undefind
--非同步函式只能通過使用回撥函式來獲取非同步API執行結果
function getMsg (callback) { setTimeout(function () { callback ({ msg: 'Hello Node.js' }) }, 2000); } getMsg (function (msg) { console.log(msg); });
2.同步API, 非同步API的區別(程式碼執行順序)
-同步API從上到下依次執行,前面程式碼會阻塞後面程式碼的執行
for (var i = 0; i < 100000; i++) { console.log(i); } console.log('for迴圈後面的程式碼');
-非同步API不會等待API執行完成後再向下執行程式碼
console.log('程式碼開始執行'); setTimeout(() => { console.log('2秒後執行的程式碼')}, 2000); setTimeout(() => { console.log('"0秒"後執行的程式碼')}, 0); console.log('程式碼結束執行');
執行順序:
同步程式碼執行區-->非同步程式碼執行區-->回撥函式佇列-->同步程式碼執行區
6. 非同步函式
非同步函式是非同步程式設計語法的終極解決方案,它可以讓我們將非同步程式碼寫成同步的形式,讓程式碼不再有回撥函式巢狀,使程式碼變得清晰明瞭。
const fn = async () => {};
async function fn () {}
1. 普通函式定義前加async關鍵字 普通函式變成非同步函式
2. 非同步函式預設返回promise物件
3. 在非同步函式內部使用return關鍵字進行結果返回 結果會被包裹的promise物件中 return關鍵字代替了resolve方法
4. 在非同步函式內部使用throw關鍵字丟擲程式異常
5. 呼叫非同步函式再鏈式呼叫then方法獲取非同步函式執行結果
6. 呼叫非同步函式再鏈式呼叫catch方法獲取非同步函式執行的錯誤資訊
·await關鍵字
1. await關鍵字只能出現在非同步函式中
2. await promise await後面只能寫promise物件 寫其他型別的API是不不可以的
3. await關鍵字可是暫停非同步函式向下執行 直到promise返回結果
示例:
1 const fs =require('fs') 2 const promisify = require('util').promisify 3 const readFile = promisify(fs.readFile) 4 5 async function run(argument) { 6 // body... 7 let r1 = await readFile('./1.txt','utf8'); 8 let r2 = await readFile('./2.txt','utf8'); 9 let r3 = await readFile('./3.txt','utf8'); 10 console.log(r1); 11 console.log(r2); 12 console.log(r3); 13 } 14 15 run();