vue - ES6模塊化、promise、webpack打包(所在在學(xué)的朋友們先看這篇,看了不吃虧)

首先我要說明一下,沒錯,還是沒有進入vue,劉備請諸葛亮三次都可以了吧,我這也是第三次了,也絕對是最后一次了,我應(yīng)經(jīng)摸透了因為,最后的webpack打包加上一個git學(xué)了過后我就去vue了。

為什么要說先看這篇,其實跟我們今天的主題webpack沒有太大關(guān)系,昨天學(xué)了一下webpack,其實內(nèi)容沒多少,webpack的內(nèi)容無非就是參考文檔去怎么做,然后最主要的js、html生成、css、字體圖標、圖片來打包包括開啟一個webpack服務(wù)器。但是我們今天的主要內(nèi)容,但是我要說的是比較重要的是,在學(xué)的朋友們,正在學(xué)包括后面在學(xué)的朋友們,作為一個程序員還在手寫筆記嗎?我也是昨天才知道手寫筆記的就我一個,我都驚了,我那么大一本筆記本,又長又厚的,我都做了那么多了,居然現(xiàn)在才知道,屬實太虧了,畢竟也是那個道理,如果后面工作不可能去翻書吧,優(yōu)不優(yōu)雅暫且不說,這耗費的時間就離譜雖然我自己做的筆記,我大概知道哪個知識點在哪一頁。

那么既然不太推薦手寫筆記了,那要用什么來做呢,程序員必備——Markdown!而他比較好的一款編輯器——Typora,昨天也花了一點時間了解了一下它有哪些功能哪些快捷鍵,確實這樣做筆記方便查找,而且省時最主要的,我原來學(xué)內(nèi)容可能內(nèi)容沒多少,但是也挺多的,滿打滿算都是一天的時間,反正現(xiàn)在有了這個,特別是代碼部分,有時候我還要手寫代碼,這個直接一個截圖的事情,你可以自己想想節(jié)省了多少時間。

至于我以前在筆記本上的,我的打算是,暴力一點,直接全 背 下 來。

回到我們今天的主題上來,首先第一個內(nèi)容說一下vue的前提基礎(chǔ),首先es6的模塊化,首先知道commanjs吧,是我們node的規(guī)則,require、exports都是他的語法,但他不是標準推薦的,真正的正統(tǒng)標準是ES6模塊化,而且commanjs只支持后端,而es6支持前后端。

他的一個語法規(guī)則:

1.1

導(dǎo)入為import 暴露共享成員export 沒有了s

如果我們node.js要使用es6模塊化的話首先版本號是要大于14.15.1的,其次需要在package.json添加“type”:“module”

關(guān)于他的導(dǎo)入導(dǎo)出一共有兩大類,第一類是默認導(dǎo)入導(dǎo)出。

export default 和 import 自定義 from ‘路徑’ 注意路徑必須添加后綴js跟我們的commanjs不一樣

let x = 19
let y = 29
function show() {}

export default  {
    x,
    show
}
import m1 from './默認導(dǎo)出.js'

console.log(m1);

然后按需導(dǎo)出 export const a = 1 就是誰要導(dǎo)出就在定義它的前面加一個export

按需導(dǎo)入 import {a} from ‘’ 這個要注意的是花括號里面的名字不再自定義必須和我們導(dǎo)出的一致,但是我們可以用as重命名

export let x = 10
export function show() {console.log('hello vue');}
import {x, show} from './按需導(dǎo)出.js'


console.log(x, show);

最后是我們的直接導(dǎo)入,直接導(dǎo)入其實也挺常用比如css,或者js直接就是一段代碼,可以直接導(dǎo)入進來不使用,他們自己有自己的用處

for(let i = 0; i < 5; i++) {
    console.log(i);
}
import './直接導(dǎo)入代碼.js'

有一說一,這個代碼塊跟typora一樣,看來這一步棋走對了。

然后看到我們的promise這個構(gòu)造函數(shù)

2.1

先了解一下回調(diào)地獄的問題吧,什么叫做回調(diào)地獄,就是我們多層嵌套回調(diào)函數(shù),本身就是回調(diào)函數(shù),還一層一層嵌套,他執(zhí)行了才去執(zhí)行里面的,其實也就是我們的高階函數(shù),那么這個時候就有問題了,我們要改上面的代碼后面也要跟著改,而且大量冗余的代碼可讀性也差。

2.2

然后說回到我們的promise,沒錯它本身是個構(gòu)造函數(shù),然后他的prototype上面有一個.then的方法,所以他的實例是可以用的,這個.then是個什么方法,他就是用來預(yù)先指定成功或者失敗的回調(diào)函數(shù)的,成功是必選參數(shù),失敗是可選。

比如我們下面通過一個案例來說,基于回調(diào)來讀取內(nèi)容,一個文件夾下面三個txt,以前的做法不用多說了的通過fs讀完一個又在里面嵌套一個,這就是典型的回調(diào)地獄。

我們的fs模塊不支持promise的方法所以我們需要下載一個包then-fs

import thenfs from 'then-fs'


thenfs.readFile('./files/1.txt', 'utf-8').then((r1) => console.log(r1))
thenfs.readFile('./files/2.txt', 'utf-8').then((r2) => console.log(r2))
thenfs.readFile('./files/3.txt', 'utf-8').then((r3) => console.log(r3))

可以看到通過promise的方法能夠輸出出來,但是有一個問題順序不太對,這里是因為異步的原因,后面會說到

2.3

先來解決我們的順序問題,怎么樣可以讓他們按照順序來呢?

想通一件事情,我們的thenfs讀取出來是一個promise的實例對象所以我們才能在后面用then這個方法,如果我們在成功的回到函數(shù)里先輸出然后返回下一個promise實例對象呢?

import thenfs from 'then-fs'

thenfs.readFile('./files/1.txt', 'utf8').then((r1) => {
    console.log(r1);
    return thenfs.readFile('./files/2.txt', 'utf8')
}).then((r2) => {
    console.log(r2);
    return thenfs.readFile('./files/3.txt', 'utf8')
}).then((r3) => console.log(r3))
file

2.4

捕獲錯誤

我們promise有一個捕獲錯誤的方法,防止前面因為什么東西發(fā)生錯誤,而導(dǎo)致整盤崩潰,當(dāng)然如果你大概知道是哪里可能有點問題也可以吧這個方法前移,那么這樣就會繼續(xù)執(zhí)行后面的

import thenfs from 'then-fs'

/* thenfs.readFile('./files/11.txt', 'utf-8').then((r1) => {
    console.log(r1);
    return thenfs.readFile('./files/2.txt', 'utf-8') //這里不做失敗的回調(diào)函數(shù),當(dāng)我們成功后是不是又通過return反悔了一個thenfs創(chuàng)造的promise的實例對象
}).then((r2) => {
    console.log(r2);
    return thenfs.readFile('./files/3.txt', 'utf-8')
}).then((r3) => {
    console.log(r3);
}).catch((err) => {
    console.log(err.message);
}) */

thenfs.readFile('./files/11.txt', 'utf-8')
.catch((err) => {
    console.log(err.message);
})
.then((r1) => {
    console.log(r1);
    return thenfs.readFile('./files/2.txt', 'utf-8') //這里不做失敗的回調(diào)函數(shù),當(dāng)我們成功后是不是又通過return反悔了一個thenfs創(chuàng)造的promise的實例對象
})
.then((r2) => {
    console.log(r2);
    return thenfs.readFile('./files/3.txt', 'utf-8')
})
.then((r3) => {
    console.log(r3);
})
file

2.5

promise.all方法這是用來發(fā)起并行的異步操作的,什么意思,就是一個等待機制,多個異步操作,等待他們?nèi)客瓿刹艜?zhí)行then里面的函數(shù)

import thenfs from 'then-fs'

let arr =[
    thenfs.readFile('./files/1.txt', 'utf-8'),
    thenfs.readFile('./files/2.txt', 'utf-8'),
    thenfs.readFile('./files/3.txt', 'utf-8')
]

Promise.all(arr).then((r) => console.log(r))
file

注意輸出為一個數(shù)組,并且輸出順序使我們數(shù)組里面的執(zhí)行順序。

與之對應(yīng)的還有一個promise.race方法,他與all一起都是發(fā)起并行操作,但是他是一旦有人執(zhí)行完,就輸出,意思就是最快的那一個

2.6

來一個案例,封裝一個promise獲取文件的函數(shù),這個函數(shù)最主要的是要搞懂我們的回調(diào)與then之間這的關(guān)系,return 一個 new promise創(chuàng)造一個實例,而他只是形式上的promise實例對象,還需要往里面添加一個函數(shù),這個函數(shù)兩個參數(shù)就是用來接受then的兩個成功和失敗的函數(shù),所以這兩個參數(shù)是函數(shù),再在里面來讀取,fs的操作步驟,也有失敗和結(jié)果去把結(jié)果給到剛才對應(yīng)的兩個參數(shù)

import fs from 'fs'
function getTxt(Fpath,type) {
    return new Promise(function(suc, wro)  {
        fs.readFile(Fpath, type, (err, result) => {
            if(err) return wro(err.message)
            suc(result)
        })
    })
}

getTxt('./files/1.txt', 'utf8').then((r1) => {
    console.log(r1)
},(err) => {
    console.log(err)
})
file

2.7

簡化異步操作 。

剛才我們的不管是all方法還是按順序執(zhí)行的函數(shù)是不是都是為了能讓我們的異步操作能按照順序執(zhí)行出來,下面是不僅執(zhí)行了異步操作而且還能按照順序執(zhí)行出來的簡化步驟用到await、async

import thenfs from 'then-fs'

async function getFile() {
    const r1 = await thenfs.readFile('../promise/files/1.txt', 'utf-8') 
    console.log(r1);
    const r2 = await thenfs.readFile('../promise/files/2.txt', 'utf-8') 
    console.log(r2);
    const r3 = await thenfs.readFile('../promise/files/3.txt', 'utf-8') 
    console.log(r3);
}

getFile()

function中用到await,函數(shù)就必須被async修飾。

不加await就是promise實例,加了就能返回值直接輸出。

在await第一個之前是同步輸出,后面都為異步任務(wù)

import thenfs from 'then-fs'
console.log('A');
async function getFile() {
    console.log('B')
    const r1 = await thenfs.readFile('../promise/files/1.txt', 'utf-8') 
    const r2 = await thenfs.readFile('../promise/files/2.txt', 'utf-8') 
    const r3 = await thenfs.readFile('../promise/files/3.txt', 'utf-8') 
    console.log(r1,r2,r3);
    console.log('D');
}
getFile()
console.log('C');

這個你認為輸出出來是多少?

ABCr123最后D

事件流,時間循環(huán)我自己口述一遍吧,之前也說過的,我們的任務(wù)分為同步任務(wù)和異步任務(wù),同步任務(wù)會優(yōu)先在主棧道上執(zhí)行完,異步任務(wù)會根據(jù)宿主環(huán)境在那里執(zhí)行,但是異步任務(wù)都是有回調(diào)函數(shù)的,所以執(zhí)行了就會把函數(shù)放到異步任務(wù)的排列隊伍,等到同步任務(wù)執(zhí)行完,就會來按照順序執(zhí)行異步任務(wù)。

3.1

js又把異步任務(wù)進一步劃分了宏任務(wù)和微任務(wù)。

宏任務(wù):比如ajax、計時器、文件操作等

微任務(wù):promise那幾個方法、prcess.nextTick等

在異步任務(wù)中會優(yōu)先執(zhí)行宏任務(wù)再去檢查這個宏任務(wù)里面的微任務(wù),然后再去執(zhí)行宏任務(wù)這樣一個循環(huán),來看一個經(jīng)典面試題,你看輸出的什么?

console.log('1');
setTimeout(() => {
 console.log('2');   
 new Promise (function(resolve) {
     console.log('3');
     resolve()
 }).then(function() {
     console.log('4');
 })
});
new Promise(function(resolve) {
    console.log('5');
    resolve()
}).then(function() {
    console.log('6');
})
setTimeout(() => {
    console.log('7');   
    new Promise (function(resolve) {
        console.log('8');
        resolve()
    }).then(function() {
        console.log('9');
    })
   });
     ```
正確答案:156234789

這個最大的難點我覺得在于當(dāng)我們進入一個作用域后,會是一個全新的作用域,在這個里面再去重新看待里面的一些任務(wù),就相當(dāng)于你現(xiàn)在在這個作用域里面就是全局作用域

4.

進入webpack。

webpack本質(zhì)上是一個第三方模塊包,他可以起到壓縮、翻譯、打包、降級的作用。

webpack環(huán)境準備:

yarn init 初始化

yarn add webpack

在package里面添加執(zhí)行命令“build” :“webpack”

反正webpack始終要記住一點他只支持js,其他的都需要去文檔上看怎么轉(zhuǎn)過來。

而且他的操作也比較規(guī)律化,先定義好文件,css要有css文件,字體圖標要有字體圖標文件,然后要跟我們的入口文件掛上鉤,像img圖片、字體圖標這些需要動態(tài)創(chuàng)建在入口文件里面,css直接導(dǎo)入,包括更改默認出入口,加載器、插件這些都是在webpack.config.js這個配置文件里面改。

另外的注意點就是我們的圖片處理只針對于img標簽,背景圖片會被css解析的,但是最好還是要做圖片處理,因為如果type為asset的話,會以8kb作為一個區(qū)分
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在了解Promise對象之前,我們有必要先來了解一下什么是回調(diào)。其實大家對于回調(diào)應(yīng)該都不陌生。將函數(shù)作為參數(shù),當(dāng)主...
    o0ther閱讀 237評論 0 0
  • 如果瀏覽已經(jīng)有了Promise對象,那么頁就說明瀏覽器的js引擎里已經(jīng)有了Promsise隊列,這樣就可以利用Pr...
    羊烊羴閱讀 580評論 0 0
  • 作者: kim先生 來源: 自創(chuàng) 今天我們講的是ES6中的Promise這個異步操作對象。在學(xué)習(xí)Promise之前...
    前端進階體驗閱讀 819評論 0 0
  • 一.Promise的含義和意義 1.什么是PromisePromise是抽象異步處理對象以及對其進行各種操作的組件...
    nightZing閱讀 3,514評論 3 10
  • 事件循環(huán) JS運行的環(huán)境稱之為宿主環(huán)境。 執(zhí)行棧:call stack,一個數(shù)據(jù)結(jié)構(gòu),用于存放各種函數(shù)的執(zhí)行環(huán)境,...
    欣欣l閱讀 457評論 0 0

友情鏈接更多精彩內(nèi)容