首先解釋一下什麼是同步、什麼是異步
同步:做飯的時候,先燒水,等水燒好的時候再去做菜
異步:做好的時候,先燒水,等待水燒好的過程中,同時去做菜
使用promise的目的就是爲了避免 callback hell(地獄回調)例如:
setTimeout(() => {
console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
}, 3000)
}, 2000)
}, 1000)
像這種代碼可讀性和可維護性都不高,所以es6才提出了promise這種方法。
promise一共有三種狀態
1.pending //既不是成功,也不是失敗
2.fulfilled //成功
3. rejected //失敗
以下是例子
//resolve代表成功,reject代表失敗
new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log(1)
resolve()
},1000).then(res=>{
setTimeout(()=>{
console.log(2)
},2000)
})
})
這樣就解決了地獄回調的問題。
除此之外,promise還有兩個很重要的方法 Promise.all
Promise.all代表等待全部promise執行完成後再執行。
舉個例子
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
resolve('p1') //可以進行傳參
}, 1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p2')
resolve('p2')
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p3')
resolve('p3')
}, 3000)
})
Promise.all([p1, p2, p3]).then(res => {
console.log('全部完成')
console.log(res)
}).catch(err => {
console.log('失敗')
console.log(err)
})
promise.all會等待p1,p2,p3完成請求之後纔會執行,如果執行失敗纔會進入catch方法。
console的結果如下:
其中promise.all成功調用之後res接受的參數是p1、p2、p3 resolve()傳遞進來的。
如果我們把p1、p2、p3 其中一個改爲調用失敗的話
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('p1')
reject('p1') //可以進行傳參
}, 1000)
})
那麼promise.all就會執行失敗,也就是promise.all一定要三個都執行成功之後才能夠成功執行。
還有一個方法是Promise.race,它的意思是,只要有一個任務完成了就算是完成了,還是剛剛那個例子,把Promise.all改爲Promise.race的話,輸入的結果如下:
promise.race一般用於判斷是否請求超時。
async、 await
在小程序中默認是不支持async、await
的,如果需要使用的話,方法如下
1.在你的項目中創建一個文件夾utils
2.在utils文件夾下創建一個js文件runtime.js
runtime.js的代碼如下:runtime.js
3.在你需要使用的小程序js中引入
//注意這裏一定要用regeneratorUntime,不用的話會報錯
import regeneratorUntime from '../../utils/runtime.js'
然後就可以開始使用 async await
了。
那麼async await怎麼使用呢?下面舉個例子說明async、await
怎麼使用
首先定義一個定時的函數
timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(1)
resolve('resolve')
}, 1000)
})
}
(這個函數會在1s之後在控制檯打印出一個1)
然後我需要在一個函數中調用這個函數並取得這個值,例如我需要在foo這個函數中調用這個方法,然後在頁面初始渲染的時候渲染這個foo()
函數
async foo(){
this.timeout()
}
顯然如果使用上面那一段代碼的話在控制檯是打印不出1的,因爲timeout()
函數是一個異步的操作
所以我們就需要使用到async、await
方法
async foo(){
let res = await this.timeout()
console.log(res)
}
這樣才能保證,timeout()函數執行完成之後才賦值給res
注意! 使用await前面一定要有一個async,不然的話執行是沒有效果的。
結果如下:
大家可以看一下代碼行數,是不是先執行了timeout這個方法然後才執行foo函數中的console。
以上就是簡單的async、await
的簡單使用方法,實際使用中肯定比這個複雜的多,希望這篇文章對大家有所幫助