03、Promise,Vue-cli搭建專案
Promise 物件
看看一個例子
function fn1() {
setTimeout(()=>{
console.log('fn1')
}, 1000)
}
function fn2() {
setTimeout(()=>{
console.log('fn2')
}, 1000)
}
function fn3() {
setTimeout(()=>{
console.log('fn3')
}, 1000)
}
對於以上程式碼如何實現: 1秒鐘之後輸出 fn1, 再過疫苗輸出 fn2, 再過1秒輸出 fn3 ?
可如下改裝:
function fn1(callback) {
setTimeout(()=>{
console.log('fn1')
callback()
}, 1000)
}
function fn2(callback) {
setTimeout(()=>{
console.log('fn2')
callback()
}, 1000)
}
function fn3() {
setTimeout(()=>{
console.log('fn3')
}, 1000)
}
fn1(function(){
fn2(function(){
fn3()
})
})
回撥地獄!
什麼是 Promise
參考阮一峰 ES6教程。
Promise 是一個物件,物件裡儲存一個狀態,這個狀態是可以隨著內部的執行轉化的,為以下三種狀態之一:等待態(Pending)、完成態(Fulfilled)、拒絕態(Rejected)。
一開始,我們先設定好等狀態從 pending 變成 fulfilled 和 rejected 的預案(當成功後我們做什麼,失敗時我們做什麼)。
Promise 啟動之後,當滿足成功的條件時我們讓狀態從 pending 變成 fullfilled (執行 resolve);當滿足失敗的條件,我們讓狀態從 pending 變成 rejected(執行 reject)
Promise 範例
範例1
Promise.prototype.then / Promise.prototype.catch
function getIp() {
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getIp', true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText) // {"ip":"58.100.211.137"}
resolve(retJson.ip)
}
xhr.onerror = function(){
reject('獲取IP失敗')
}
xhr.send()
})
return promise
}
function getCityFromIp(ip) {
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getCityFromIp?ip='+ip, true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText) // {"city": "hangzhou","ip": "23.45.12.34"}
resolve(retJson.city)
}
xhr.onerror = function(){
reject('獲取city失敗')
}
xhr.send()
})
return promise
}
function getWeatherFromCity(city) {
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getWeatherFromCity?city='+city, true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText) //{"weather": "晴天","city": "beijing"}
resolve(retJson)
}
xhr.onerror = function(){
reject('獲取天氣失敗')
}
xhr.send()
})
return promise
}
getIp().then(function(ip){
return getCityFromIp(ip)
}).then(function(city){
return getWeatherFromCity(city)
}).then(function(data){
console.log(data)
}).catch(function(e){
console.log('出現了錯誤', e)
})
Promise.all
範例2
function getCityFromIp(ip) {
var promise = new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest()
xhr.open('GET', 'https://easy-mock.com/mock/5ac2f80c3d211137b3f2843a/promise/getCityFromIp?ip='+ip, true)
xhr.onload = function(){
var retJson = JSON.parse(xhr.responseText) // {"city": "hangzhou","ip": "23.45.12.34"}
resolve(retJson)
}
xhr.onerror = function(){
reject('獲取city失敗')
}
xhr.send()
})
return promise
}
var p1 = getCityFromIp('10.10.10.1')
var p2 = getCityFromIp('10.10.10.2')
var p3 = getCityFromIp('10.10.10.3')
//Promise.all, 當所有的 Promise 物件都完成後再執行
詳情,評價,購買人群
Promise.all([p1, p2, p3]).then(data=>{
console.log(data)
})
Pomise.all的使用
Promise.all可以將多個Promise例項包裝成一個新的Promise例項。同時,成功和失敗的返回值是不同的,成功的時候返回的是一個結果陣列,而失敗的時候則返回最先被reject失敗狀態的值。
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promse.reject('失敗')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失敗了,打出 '失敗'
})
Promse.all在處理多個非同步處理時非常有用,比如說一個頁面上需要等兩個或多個ajax的資料回來以後才正常顯示,在此之前只顯示loading圖示。
let wake = (time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${time / 1000}秒後醒來`)
}, time)
})
}
let p1 = wake(3000)
let p2 = wake(2000)
Promise.all([p1, p2]).then((result) => {
console.log(result) // [ '3秒後醒來', '2秒後醒來' ]
}).catch((error) => {
console.log(error)
})
需要特別注意的是,Promise.all獲得的成功結果的陣列裡面的資料順序和Promise.all接收到的陣列順序是一致的,即p1的結果在前,即便p1的結果獲取的比p2要晚。這帶來了一個絕大的好處:在前端開發請求資料的過程中,偶爾會遇到傳送多個請求並根據請求順序獲取和使用資料的場景,使用Promise.all毫無疑問可以解決這個問題。
二、Promise.race的使用
顧名思義,Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])裡面哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 開啟的是 'failed'
})
//Promise.all, 當所有的 Promise 物件都完成後再執行
Promise.race([p1, p2, p3]).then(data=>{
console.log(data)
})
對於開頭回撥地獄的解決
function fn1() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn1...')
resolve()
}, 1000)
})
}
function fn2() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn2...')
resolve()
}, 1000)
})
}
function fn3() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('fn3...')
resolve()
}, 1000)
})
}
function onerror() {
console.log('error')
}
fn1().then(fn2).then(fn3).catch(onerror)
---
# 使用腳手架搭建專案
## 安裝
開啟終端,切換到一個經常使用的專案目錄,如
cd ~/projects
全域性安裝 vue-cli
npm install -g vue-cli
使用 vue-cli 建立 基於webpack模板的新專案
vue init webpack vue-evernote-client
![image](http://upload-images.jianshu.io/upload_images/3680331-2d24a6e125a00eb8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
按回車![image](http://upload-images.jianshu.io/upload_images/3680331-f845ed9be840e3d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
按回車![image](http://upload-images.jianshu.io/upload_images/3680331-2acdffa3b4572408.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
按回車![image](http://upload-images.jianshu.io/upload_images/3680331-f4d15d222beab92e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用預設選項 Runtime + Compile 即可,直接按回車![image](http://upload-images.jianshu.io/upload_images/3680331-9c03ebac148c260f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
輸入 Y,按回車![image](http://upload-images.jianshu.io/upload_images/3680331-808dcaf0fc96a4a8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
輸入 n,按回車![image](http://upload-images.jianshu.io/upload_images/3680331-09d68e206aa3280b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
輸入 n,按回車![image](http://upload-images.jianshu.io/upload_images/3680331-7ad18f8d05fa766b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
輸入 n,按回車![image](http://upload-images.jianshu.io/upload_images/3680331-3eb0aa018d1fe6e3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用預設的 npm 作為包管理工具,直接按回車
等待安裝,安裝完畢後
進入當前專案目錄
cd vue-evernote-client
安裝依賴
npm install
![image](http://upload-images.jianshu.io/upload_images/3680331-b196241e84e1386a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
啟動server
npm run dev
瀏覽器開啟 [http://localhost:8080](http://localhost:8080/ "null") ,即可看到搭建好的初始介面
![image](http://upload-images.jianshu.io/upload_images/3680331-9adbc38fedef364a.jpg-middle?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
可以使用編輯器開啟 vue-evernote-client 這個目錄,閱讀程式碼,目前我們暫時只需要關注 src 這個目錄即可。
|-- build // 專案構建(webpack)相關程式碼
| |-- build.js // 生產環境構建程式碼
| |-- check-version.js // 檢查node、npm等版本
| |-- dev-client.js // 熱過載相關
| |-- dev-server.js // 構建本地伺服器
| |-- utils.js // 構建工具相關
| |-- webpack.base.conf.js // webpack基礎配置
| |-- webpack.dev.conf.js // webpack開發環境配置
| |-- webpack.prod.conf.js // webpack生產環境配置
|-- config // 專案開發環境配置
| |-- dev.env.js // 開發環境變數
| |-- index.js // 專案一些配置變數
| |-- prod.env.js // 生產環境變數
| |-- test.env.js // 測試環境變數
|-- src // 原始碼目錄
| |-- components // vue公共元件
| |-- apis // 請求介面
| |--utils // 工具庫
| |-- views // 業務元件
| |-- store // vuex的狀態管理
| |-- App.vue // 頁面入口檔案
| |-- main.js // 程式入口檔案,載入各種公共元件
|-- static // 靜態檔案,比如一些圖片,json資料等
| |-- data // 群聊分析得到的資料用於資料視覺化
|-- .babelrc // ES6語法編譯配置
|-- .editorconfig // 定義程式碼格式
|-- .gitignore // git上傳需要忽略的檔案格式
|-- README.md // 專案說明
|-- favicon.ico
|-- index.html // 入口頁面
|-- package.json // 專案基本資訊
相關文章
- Vue-CLI 專案搭建Vue
- Vue-Cli 專案基礎搭建Vue
- 使用vue-cli搭建VUE專案Vue
- promise專題--手寫promise03Promise
- Vue-cli搭建完專案,各檔案解釋Vue
- Vue-Cli 3.0從0 開始搭建專案(篇1)Vue
- Vue-cli 3.x搭建專案還要做什麼?之一【新建專案與配置】Vue
- vue-cli 專案結構Vue
- vue 快速入門 系列 —— 使用 vue-cli 3 搭建一個專案(上)Vue
- vue 快速入門 系列 —— 使用 vue-cli 3 搭建一個專案(下)Vue
- PHP開發環境 03 - 使用KFKDock搭建PHP專案環境PHP開發環境
- vue-cli搭建Vue
- 第一個 vue-cli專案Vue
- vue-cli構建vue專案Vue
- 自定義Vue-cli專案模板Vue
- Vue-cli 3.x搭建專案還要做什麼?之二【Vue Router】Vue
- vue-cli構建專案使用 lessVue
- 在vue-cli專案中使用echartsVueEcharts
- vue-cli專案結構詳解Vue
- vue(16)vue-cli建立專案以及專案結構解析Vue
- vue-cli 專案下生成二維碼Vue
- vue-cli專案升級webpack4VueWeb
- vue-cli腳手架專案構成Vue
- VUE-CLI webpack 專案打包部署上線VueWeb
- Nginx-03-Nginx 專案架構Nginx架構
- luffy路飛專案上線03
- vue-cli 搭建的專案處理不同環境下請求不同域名的問題Vue
- 在vue-cli專案設定代理proxyTableVue
- 番外:深入理解Promise - 03 Promise的幾個重要問題Promise
- Promise 讓你的專案更有逼格Promise
- Vue-cli 腳手架搭建Vue
- Rust 程式設計小專案:WebServer 03Rust程式設計WebServer
- vue-cli + es6 + axios專案踩坑VueiOS
- vue-cli快速構建專案簡單介紹Vue
- 使用gulp搭建專案
- Django專案搭建流程Django
- vue專案的搭建Vue
- webpack 搭建 vue 專案WebVue