在這個世界上取得成就的人,都努力去尋找他們想要的機會,若是找不到機會,他們便本身創造機會。
你好,我是夢陽辰!期待與你相遇!css
提及路由你想起了什麼?
路由是一個網絡工程裏面的術語。
路由( routing )就是經過互聯的網絡把信息從源地址傳輸到目的地址的活動.—維基百科html
在生活中,咱們有沒有據說過路由的概念呢?
固然了,路由器嘛.路由器是作什麼的?你有想過嗎?
路由器提供了兩種機制:
路由和轉送.前端
√路由是決定數據包歷來源到目的地的路徑.
√轉送將輸入端的數據轉移到合適的輸出端.vue
路由中有一個很是重要的概念叫路由表.
√路由表本質上就是一個映射表,決定了數據包的指向.html5
前端渲染和後端渲染webpack
後端渲染:再後端寫前端代碼渲染(jsp)。git
前端渲染:前端渲染後臺返回的數據。github
後端處理url和頁面之間的映射關係。web
早期的網站開發整個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可是頁面不刷新呢?
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的單頁面應用中,頁面的路徑的改變就是組件的切換.
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中語法有所不一樣。
使用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*/
嵌套路由是一個很常見的功能
好比在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*/
傳遞參數主要有兩種類型: 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表示當前活躍的路由。
正如其名,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) => { // ...})
補充二:上面咱們使用的導航守衛,被稱之爲全局守衛.
路由獨享的守衛.
組件內的守衛.
爲何使用導航守衛?
保存組件的狀態。不讓組件銷燬。
keep-alive是Vue內置的一個組件,可使被包含的組件保留狀態,或避免從新渲染。
它們有兩個很是重要的屬性:
include -字符串或正則表達,只有匹配的組件會被緩存
exclude -字符串或正則表達式,任何匹配的組件都不會被緩存
router-view也是一個組件,若是直接被包在keep-alive裏面,全部路徑匹配到的視圖組件都會被緩存∶
<keep-alive> <router-view/></keep-alive>
實現思路:
1.若是在下方有一個單獨的TabBar組件,你如何封裝自定義TabBar組件,在APP中使用讓TabBar出於底部,而且設置相關的樣式
2.TabBar中顯示的內容由外界決定
定義插槽
flex佈局平分TabBar
3.自定義TabBarItem,能夠傳入圖片和文字
定義TabBarItem,而且定義兩個插槽:圖片、文字。
給兩個插槽外層包裝div,用於設置樣式。
填充插槽,實現底部TabBar的效果
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.