在這個世界上取得成就的人,都努力去尋找他們想要的機會,如果找不到機會,他們便自己創造機會。
你好,我是夢陽辰!期待與你相遇!
01.什麼是路由?
說起路由你想起了什麼?
路由是一個網絡工程裏面的術語。
路由( routing )就是通過互聯的網絡把信息從源地址傳輸到目的地址的活動.—維基百科
在生活中,我們有沒有聽說過路由的概念呢?
當然了,路由器嘛.路由器是做什麼的?你有想過嗎?
路由器提供了兩種機制:
路由和轉送.
√路由是決定數據包從來源到目的地的路徑.
√轉送將輸入端的數據轉移到合適的輸出端.
路由中有一個非常重要的概念叫路由表.
√路由表本質上就是一個映射表,決定了數據包的指向.
前端渲染和後端渲染
後端渲染:再後端寫前端代碼渲染(jsp)。
前端渲染:前端渲染後臺返回的數據。
後端路由
後端處理url和頁面之間的映射關係。
早期的網站開發整個HTML頁面是由服務器來渲染的.
服務器直接生產渲染好對應的HTML頁面,返回給客戶端進行展示.
但是,一個網站,這麼多頁面服務器如何處理呢?
一個頁面有自己對應的網址,也就是URL.
URL會發送到服務器,服務器會通過正則對該URL進行匹配,並且最後交給一個Controller進行處理.
Controller進行各種處理,最終生成HTML或者數據,返回給前端.
這就完成了一個IO操作.
上面的這種操作,就是後端路由.
當我們頁面中需要請求不同的路徑內容時,交給服務器來進行處理,服務器渲染好整個頁面,並且將頁面返回給客戶頓.這種情況下渲染好的頁面,不需要單獨加載任何的js和css,可以直接交給瀏覽器展示,這樣也有利於SEO的優化.
後端路由的缺點:
一種情況是整個頁面的模塊由後端人員來編寫和維護的.
另一種情況是前端開發人員如果要開發頁面,需要通過PHP和Java等語言來編寫頁面代碼.
加粗樣式
而且通常情況下HTML代碼和數據以及對應的邏輯會混在一起,編寫和維護都是非常糟糕的事情.
前後端分離階段
前端渲染後臺發送回來的數據,後端負責返回數據。
前後端分離階段︰
隨着Ajax的出現,有了前後端分離的開發模式.
後端只提供API來返回數據,前端通過Ajax獲取數據,並且可以通過JavaScript將數據渲染到頁面中.
這樣做最大的優點就是前後端責任的清晰,後端專注於數據上,前端專注於交互和可視化上.
並且當移動端(iOS/Android)出現後,後端不需要進行任何處理,依然使用之前的一套API即可.目前很多的網站依然採用這種模式開發.
前端路由階段(單頁面復應用階段)
單頁面復應用階段:
spa頁面
其實SPA最主要的特點就是在前後端分離的基礎上加了一層前端路由
也就是前端來維護一套路由規則
整個網頁只有一個html頁面。
前端路由主要是負責路由關係,即一個url對應一個組件,前端路由管理url對應的映射關係。
前端路由的核心是什麼呢?
改變URL,但是頁面不進行整體的刷新。如何實現呢?
url的hash&html5的history
如何改變url但是頁面不刷新呢?
URL的hash
URL的hash也就是錨點(#),本質上是改變window.location的href屬性.
我們可以通過直接賦值location.hash來改變href,但是頁面不發生刷新
在html5的history模式:pushState
back()方法刪除棧頂。
replaceState()方法替換。
目前前端流行的三大框架,都有自己的路由實現:
Angular的ngRouter
React的ReactRouter
Vue的vue-router
vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用於構建單頁面應用。
我們可以訪問其官方網站對其進行學習: https://router.vuejs.org/zh/
vue-router是基於路由和組件的
路由用於設定訪問路徑,將路徑和組件映射起來.
在vue-router的單頁面應用中,頁面的路徑的改變就是組件的切換.
安裝vue-router
cnpm install vue-router --save
或者在創建的時候可以選擇安裝路由。
步驟二:在模塊化工程中使用它(因爲是一個插件,所以可以通過Vue.use()來安裝路由功能)
在vue-cli2中
在vue-cli3/4中不需要以下配置。
≥第一步:導入路由對象,並且調用Vue.use(VueRouter)
第二步:創建路由實例,並且傳入路由映射配置
≥第三步:在Vue實例中掛載創建的路由實例
index.js
//配置路由相關的信息import vueRouter from 'vue-router'import vue from 'vue'//1.通過vue.use(插件),安裝插件vue.use(VueRouter)//2.創建vueRouter對象const routes =[]const router = new VueRouter({
//配置路由和科組件之間的應用關係
routes })//3.將router對象傳入到vue實例export default router
main.js
import router from './router'new Vue({
el:'#app',
router,//掛載
render:h=>h(App)})
render:h=>h(App)看不懂?
render (h){
return h(App);}這下懂了把,箭頭函數
在vue-cli2中在vue-cli3/4中語法有所不同。
02.vue-router基本使用
使用vue-router的步驟:
第一步:創建路由組件
第二步:配置路由映射:組件和路徑映射關係
第三步:使用路由:通過<router-link>和<router-view>
<router-link>
:該標籤是一個vue-router中已經內置的組件,它會被渲染成一個<a>
標籤.
<router-view>
:該標籤會根據當前的路徑,動態渲染出不同的組件.
網頁的其他內容,比如頂部的標題/導航,或者底部的一些版權信息等會和<router-view>
處於同一個等級.
在路由切換時,切換的是<router-view>
掛載的組件,其他內容不會發生改變.
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/></template>
注意,當a的目標路由匹配時,它<router-link>
會自動獲取.router-link-active該類。
router-link屬性
在前面的<router-link>
中,我們只是使用了一個屬性: to
,用於指定跳轉的路徑.
<router-link>
還有一些其他屬性:
<router-link to='/home' tag='li '>
tag: tag可以指定<router-link>
之後渲染成什麼組件,比如上面的代碼會被渲染成一個<li>
元素,而不是<a>
tag="button"
replace
: replace不會留下history記錄,所以指定replace的情況下,後退鍵返回不能返回到上一個頁面中
active-class:當<router-link>
對應的路由匹配成功時,會自動給當前元素設置一個router-link-active
的class,設置active-class可以修改默認的名稱.
在進行高亮顯示的導航菜單或者底部tabbar
時,會使用到該類.
但是通常不會修改類的屬性,會直接使用默認的router-link-active
即可.
因此可以對router-link-active屬性添加樣式,達到點擊表達不同的效果。
除了<router-link>
跳轉路徑,還可以通過代碼的方式修改路由
this.$router.push('/home')
戰略性總結:
render/use/mount函數
use函數用於安裝插件。
render函數的實質就是生成template模板;
mount函數就是掛載元素
動態路由的使用
根據用戶的名字,路徑也不同!
例如:
新建組件User.vue
<template>
<div>
<h3>用戶界面</h3>
<h3>我是特定用戶的信息界面</h3>
<h3>{{userName}}</h3>
</div></template><script>
export default {
name: "User",
computed:{
userName(){
//獲取處於活躍的路由
return this.$route.params.userName;
}
}
}</script><style scoped></style>
App.vue
<template>
<div id="nav">
<router-link to="/" tag="button">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link v-bind:to="'/user/'+userName">User</router-link>
<br>
<button @click="btn">點我也可以去關於(代碼跳轉)</button>
</div>
<router-view/></template><script>
export default {//代碼的方式
name:'App',
data(){
return{
userName:"mengyangchen"
}
},
methods:{
btn(){
// this.$router.push('/about')
this.$router.replace('/about')
}
}
}</script><style>#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;}#nav {
padding: 30px;}#nav a {
font-weight: bold;
color: #2c3e50;}#nav a.router-link-exact-active {
color: #42b983;}</style>
index.js
import { createRouter, createWebHistory } from 'vue-router'import Home from '../views/Home.vue'import User from '../components/User'const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{//動態路徑
path: '/user/:userName',
component: User
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}]const router = createRouter({
history: createWebHistory(process.env.BASE_URL),//history模式
routes})export default router/*//配置路由相關的信息import vueRouter from 'vue-router'import vue from 'vue'//1.通過vue.use(插件),安裝插件vue.use(VueRouter)//2.創建vueRouter對象const routes =[]const router = new VueRouter({
//配置路由和科組件之間的應用關係
routes
})//3.將router對象傳入到vue實例export default router*/
HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div></template><script>export default {
name: 'HelloWorld',
props: {
msg: String
}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>h3 {
margin: 40px 0 0;}ul {
list-style-type: none;
padding: 0;}li {
display: inline-block;
margin: 0 10px;}a {
color: #42b983;}</style>
main.js
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div></template><script>export default {
name: 'HelloWorld',
props: {
msg: String
}}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>h3 {
margin: 40px 0 0;}ul {
list-style-type: none;
padding: 0;}li {
display: inline-block;
margin: 0 10px;}a {
color: #42b983;}</style>
Home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div></template><script>// @ is an alias to /srcimport HelloWorld from '@/components/HelloWorld.vue'export default {
name: 'Home',
components: {
HelloWorld
}}</script>
About.vue
<template>
<div class="about">
<h1>This is an about page</h1>
</div></template>
路由懶加載
當打包構建應用時,Javascript包會變得非常大,影響頁面加載。
如果我們能把不同路由對應的組件分割成不同的代碼塊,然後當路由被訪問的時候才加載對應組件,這樣就更加高效了
用到時再加載。
首先,我們知道路由中通常會定義很多不同的頁面.
這個頁面最後被打包在哪裏呢?一般情況下,是放在一個js文件中.但是,頁面這麼多放在一個js文件中,必然會造成這個頁面非常的大.
如果我們一次性從服務器請求下來這個頁面,可能需要花費一定的時間,甚至用戶的電腦上還出現了短暫空白的情況.
如何避免這種情況呢?
使用路由懶加載就可以了.
路由懶加載的主要作用就是將路由對應的組件打包成一個個的js代碼塊.
只有在這個路由被訪問到的時候,才加載對應的組件
路由懶加載的效果:
路由懶加載的寫法:
將user組件改爲懶加載:
import { createRouter, createWebHistory } from 'vue-router'import Home from '../views/Home.vue'const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{//動態路徑
path: '/user/:userName',
name: 'User',
component: ()=>import('../components/User')
},
{
path: '/about',
name: 'About',
// route level code-splitting 路由懶加載
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ()=>import(/* webpackChunkName: "about" */ '../views/About.vue')
}]const router = createRouter({
history: createWebHistory(process.env.BASE_URL),//history模式
routes})export default router/*//配置路由相關的信息import vueRouter from 'vue-router'import vue from 'vue'//1.通過vue.use(插件),安裝插件vue.use(VueRouter)//2.創建vueRouter對象const routes =[]const router = new VueRouter({
//配置路由和科組件之間的應用關係
routes
})//3.將router對象傳入到vue實例export default router*/
03.vue-router嵌套路由
嵌套路由是一個很常見的功能
比如在home頁面中,我們希望通過/home/news和/home/message訪問一些內容.
一個路徑映射一個組件,訪問這兩個路徑也會分別渲染兩個組件.
實現嵌套路由有兩個步驟:
創建對應的子組件,並且在路由映射中配置對應的子路由.
在組件內部使用<router-view>
標籤.
home.vue
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<router-link to="/news">新聞</router-link> |
<router-link to="/message">消息</router-link>
<router-view/>
</div></template><script>// @ is an alias to /srcimport HelloWorld from '@/components/HelloWorld.vue'export default {
name: 'Home',
components: {
HelloWorld
}}</script>
index.js
import { createRouter, createWebHistory } from 'vue-router'const routes = [
{
path: '/',
name: 'Home',
component: ()=>import('../views/Home.vue'),
children:[
{
path:'news',
name:'HomeNews',
component:()=>import('../components/HomeNews.vue')
},{
path:'message',
name:'HomeMessage',
component:()=>import('../components/HomeMessage.vue')
}
]
},
{//動態路徑
path: '/user/:userName',
name: 'User',
component: ()=>import('../components/User.vue')
},
{
path: '/about',
name: 'About',
// route level code-splitting 路由懶加載
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ()=>import(/* webpackChunkName: "about" */ '../views/About.vue')
}]const router = createRouter({
history: createWebHistory(process.env.BASE_URL),//history模式
routes})export default router/*//配置路由相關的信息import vueRouter from 'vue-router'import vue from 'vue'//1.通過vue.use(插件),安裝插件vue.use(VueRouter)//2.創建vueRouter對象const routes =[]const router = new VueRouter({
//配置路由和科組件之間的應用關係
routes
})//3.將router對象傳入到vue實例export default router*/
04.vue-router參數傳遞
傳遞參數主要有兩種類型: params和query
params的類型:
配置路由格式: /router/:id
傳遞的方式:在path後面跟上對應的值
傳遞後形成的路徑: /router/123,/router/abc
這種方式前面已經講過。
query的類型:
配置路由格式 /router,也就是普通配置
傳遞的方式:對象中使用query的key作爲傳遞方式
傳遞後形成的路徑: /router?id=123,/router?id=abc
app.vue
<template>
<div id="nav">
<router-link to="/home" tag="button">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link v-bind:to="'/user/'+userName">User</router-link> |<!-- <router-link to="/profile">檔案</router-link>--><!--<router-link :to="{path:'/profile',query:{name:'mengyangchen',age:'20'}}">檔案</router-link>-->
<button @click="btn1">profile</button>
<br>
<button @click="btn">點我也可以去關於(代碼跳轉)</button>
</div>
<router-view/></template><script>
export default {//代碼的方式
name:'App',
data(){
return{
userName:"mengyangchen"
}
},
methods:{
btn(){
// this.$router.push('/about')
this.$router.replace('/about')
},
btn1(){
this.$router.replace({
path:'/profile',
query:{
name:'mengyangchen',
age:'19'
}
})
}
}
}</script><style>#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;}#nav {
padding: 30px;}#nav a {
font-weight: bold;
color: #2c3e50;}#nav a.router-link-exact-active {
color: #42b983;}</style>
profile.vue
<template>
<div>
<h3>我是Profile!</h3>
<h3>{{$route.query.name}}</h3>
</div></template><script>
export default {
name: "Profile"
}</script><style scoped></style>
當有大量數據的時候用query。
router和route$router
爲VueRouter實例,想要導航到不同URL,則使用$router.push
方法
$route
爲當前router跳轉對象裏面可以獲取name、path、query.params等
所有的組件都繼承自vue類的原型。
route表示當前活躍的路由。
05.vue-router全局導航守衛
正如其名,vue-router 提供的導航守衛主要用來通過跳轉或取消的方式守衛導航。有多種機會植入路由導航過程中:全局的, 單個路由獨享的, 或者組件級的。
我們來考慮一個需求:在一個SPA應用中,如何改變網頁的標題呢?
網頁標題是通過<title>
來顯示的,但是SPA只有一個固定的HTML,切換不同的頁面時,標題並不會改變.但是我們可以通過JavaScript來修改<title>
的內容.window.document.title = ‘新的標題’.
那麼在Vue項目中,在哪裏修改?
什麼時候修改比較合適呢?
生命週期的鉤子函數:
created(){}//組件創建完mounted(){}//掛載完成update(){}//界面更新完成
我們可以在created()函數完成。
import { createRouter, createWebHistory } from 'vue-router'const routes = [
{
path: '/',
name: 'Home',
component: ()=>import('../views/Home.vue'),
children:[
{//默認顯示news
path: '',
redirect:'news'
},
{
path:'news',
name:'HomeNews',
component:()=>import('../components/HomeNews.vue')
},{
path:'message',
name:'HomeMessage',
component:()=>import('../components/HomeMessage.vue')
}
],
meta: {
title: '首頁'
}
},
{//動態路徑
path: '/user/:userName',
name: 'User',
component: ()=>import('../components/User.vue'),
meta:{
title:'用戶'
}
},
{
path: '/about',
name: 'About',
// route level code-splitting 路由懶加載
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: ()=>import(/* webpackChunkName: "about" */ '../views/About.vue'),
meta: {
title: '關於'
}
},{
path: '/profile',
name:'Profile',
component:()=>import('../components/Profile.vue'),
meta: {
title: 'Profile'
}
}]const router = createRouter({
history: createWebHistory(process.env.BASE_URL),//history模式
routes})router.beforeEach((to,from,next)=>{//全局守衛
//從from 跳轉到to
document.title = to.matched[0].meta.title
console.log(to)
next()});//export default router/*//配置路由相關的信息import vueRouter from 'vue-router'import vue from 'vue'//1.通過vue.use(插件),安裝插件vue.use(VueRouter)//2.創建vueRouter對象const routes =[]const router = new VueRouter({
//配置路由和科組件之間的應用關係
routes
})//3.將router對象傳入到vue實例export default router*/
補充一:如果是後置鉤子,也就是afterEach,不需要主動調用next()函數.
然而和守衛不同的是,這些鉤子不會接受 next 函數也不會改變導航本身:
router.afterEach((to, from) => {
// ...})
補充二:上面我們使用的導航守衛,被稱之爲全局守衛.
路由獨享的守衛.
組件內的守衛.
爲什麼使用導航守衛?
06.keep-alive
保存組件的狀態。不讓組件銷燬。
keep-alive是Vue內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。
它們有兩個非常重要的屬性:
include -字符串或正則表達,只有匹配的組件會被緩存
exclude -字符串或正則表達式,任何匹配的組件都不會被緩存
router-view也是一個組件,如果直接被包在keep-alive裏面,所有路徑匹配到的視圖組件都會被緩存∶
<keep-alive>
<router-view/></keep-alive>
07.案例(TabBar)
實現思路:
1.如果在下方有一個單獨的TabBar組件,你如何封裝自定義TabBar組件,在APP中使用讓TabBar出於底部,並且設置相關的樣式
2.TabBar中顯示的內容由外界決定
定義插槽
flex佈局平分TabBar
3.自定義TabBarItem,可以傳入圖片和文字
定義TabBarItem,並且定義兩個插槽:圖片、文字。
給兩個插槽外層包裝div,用於設置樣式。
填充插槽,實現底部TabBar的效果
08.Promise(重點)
ES6中一個非常重要和好用的特性就是Promise
但是初次接觸Promise會一臉懵逼,這TM是什麼東西?
看看官方或者一些文章對它的介紹和用法,也是一頭霧水。Promise到底是做什麼的呢?
promise是異步編程的一種解決方案。
那什麼時候我們會來處理異步事件呢?
一種很常見的場景應該就是網絡請求了。
我們封裝一個網絡請求的函數,因爲不能立即拿到結果,所以不能像簡單的3+4=7一樣將結果返回。所以往往我們會傳入另外一個函數,在數據請求成功時,將數據通過傳入的函數回調出去。
如果只是一個簡單的網絡請求,那麼這種方案不會給我們帶來很大的麻煩。
但是,當網絡請求非常複雜時,就會出現回調地獄(例如求情的數據,作爲參數再次請求數據)。
Promise可以很好的解決這個問題。
我們先來看看Promise最基本的語法。
這裏,我們用一個定時器來模擬異步事件:
假設下面的data是從網絡上1秒後請求的數據console.log就是我們的處理方式。
這是我們過去的處理方式,我們將它換成Promise代碼這個例子會讓我們感覺***放屁,多此一舉
首先,下面的Promise代碼明顯比上面的代碼看起來還要複雜。
其次,下面的Promise代碼中包含的resolve、reject、then、catch都是些什麼東西?
我們先不管第一個複雜度的問題,因爲這樣的一個屁大點的程序根本看不出來Promise真正的作用。
首先,當我們開發中有異步操作時,就可以給異步操作包裝一個Promise
異步操作之後會有三種狀態我們一起來看一下這三種狀態:
pending:等待狀態,比如正在進行網絡請求,或者定時器沒有到時間。
fulfill:滿足狀態,當我們主動回調了resolve時,就處於該狀態,並且會回調.then()
reject :拒絕狀態,當我們主動回調了reject時,就處於該狀態,並且會回調.catch()
Promise 異步操作有三種狀態:pending(進行中)、fulfilled(已成功)和 rejected(已失敗)。除了異步操作的結果,任何其他操作都無法改變這個狀態。
如果不設置回調函數,Promise 內部拋出的錯誤,不會反應到外部。
對請求結果多次處理:
省略寫法:
代碼優雅而nice.
Promise的鏈式調用:
Promise的all方法:
All things come to those who wait.