ES6(三) Promise 的基本使用方式
基本用法
關於Promise的資料,網上有很多了,這裡簡單粗暴一點,直接上程式碼。
假設我們要做一個訪問後端API的函式,那麼我們可以這樣模擬一下。
const mySend = (url, data) => {
// 接收url 和data,假裝向後端提交
console.log('url:', url, data)
// 定義一個例項
const p = new Promise((resolve, reject)=>{
// resolve,reject是形式引數,可以是任意寫法,如(res, rej)
// 預設第一個引數實現的是resolve功能;
// 第二個引數實現的是reject功能。
console.log("假裝訪問了一下後端,並且獲得了資料。")
const data = {
name: 'jyk',
time: new Date().valueOf()
}
// 成功了,返回給呼叫者
resolve(data)
// 不同於return, resolve()執行完成後後面的程式碼還會執行。
console.log('resolve後的程式碼')
// 如果 resolve 被呼叫了,那麼 reject 就不會被呼叫了。
// 失敗的話,呼叫reject返回給呼叫者。
reject('失敗了')
})
return p
}
-
new Promise
先定義一個函式,用於接收呼叫者的引數。
然後生成一個Promise的例項,在裡面進行我們想要的操作。 -
resolve(data)
如果操作成功就呼叫 resolve(data) ,返回給呼叫者; -
reject('失敗了')
如果操作失敗,就呼叫reject('失敗了') ,返回給呼叫者。
注意:返回引數只能有一個,不支援多個引數,如果需要返回多個,可以組成一個物件。
有些例子會用setTimeout做演示,其實效果都一樣,不是必須弄個非同步的方式來模擬。
單次呼叫
函式寫好了,怎麼呼叫呢?其實呼叫方法和axios的使用方式很像,因為axios也是用promis封裝的。
const submit = () => {
mySend('/api/person', {id: 122})
.then((data) => {
console.log('回撥資料:', data)
})
.catch((error) => {
console.log(error)
})
}
呼叫很簡單,看著也非常眼熟對吧。
-
then 響應成功的回撥,
-
catch 響應失敗(異常)的回撥。
-
執行結果:
url-data: /api/person {id: 122}
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):52 回撥資料: {name: "jyk", time: 1612084395672}
依次呼叫
如果要多次呼叫呢?而且要得到上一次返回的資料,才能發起下一次的訪問。
const submitStep = () => {
mySend('/api/person1', [1,2,3]).then((data) => {
console.log('第一個返回:', data)
return mySend('/api/person2', data) // 發起第二次請求
}).then((data) => {
console.log('第二個返回:', data)
return mySend('/api/person3', data) // 發起第三次請求
}).then((data) => {
console.log('第三個返回:', data)
return mySend('/api/person4', data) // 發起第四次請求
}).then((data) => {
console.log('第四個返回:', data)
})
}
第一次呼叫的回撥函式裡面,使用return的方式,發起下一次呼叫。這樣就可以避免回撥地域。
- 執行結果:
url-data: /api/person1 (3) [1, 2, 3]
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):62 第一個返回: {name: "jyk", time: 1612084751425}
(index):26 url-data: /api/person2 {name: "jyk", time: 1612084751425}
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):65 第二個返回: {name: "jyk", time: 1612084751426}
(index):26 url-data: /api/person3 {name: "jyk", time: 1612084751426}
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):68 第三個返回: {name: "jyk", time: 1612084751428}
(index):26 url-data: /api/person4 {name: "jyk", time: 1612084751428}
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):71 第四個返回: {name: "jyk", time: 1612084751430}
可以注意一下time的值,前後是對應的。
批量呼叫
如果下次呼叫不需要上一次的結果呢?那麼能不能一起呼叫呢?當然是可以的。
const submitMore = () => {
Promise.all([
mySend('/api/person11', [1,2,3]),
mySend('/api/person22', [4,5,6]),
mySend('/api/person33', [7,8,9])
]).then((data) => {
console.log("一起呼叫,一起返回:")
console.log('data:', data)
console.log('data11:', data[0])
console.log('data22:', data[1])
console.log('data33:', data[2])
},(msg) => {
console.log(msg)
})
}
-
Promise.all
使用 Promise.all,把呼叫寫成陣列的形式。
返回的data也是一個數組的形式,其順序會對照上面的呼叫順序。 -
執行結果:
url-data: /api/person11 (3) [1, 2, 3]
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):26 url-data: /api/person22 (3) [4, 5, 6]
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):26 url-data: /api/person33 (3) [7, 8, 9]
(index):32 假裝訪問了一下後端,並且獲得了資料。
(index):39 resolve後的程式碼
(index):82 一起呼叫,一起返回:
(index):83 data: (3) [{…}, {…}, {…}]
0: {name: "jyk", time: 1612085029968}
1: {name: "jyk", time: 1612085029969}
2: {name: "jyk", time: 1612085029970}
length: 3__proto__: Array(0)
(index):84 data11: {name: "jyk", time: 1612085029968}
(index):85 data22: {name: "jyk", time: 1612085029969}
(index):86 data33: {name: "jyk", time: 1612085029970}
可以看到,先發起了申請,然後結果會一起返回。
小結
這樣看起來就不會暈了吧。我的想法是,先會用能夠執行起來,以後有空了在去研究原理和其他細節。
線上演示:https://naturefwvue.github.io/nf-vue-cnd/ES6/promise/
原始碼:https://github.com/naturefwvue/nf-vue-cnd/tree/main/ES6/promise
- Android——一個簡單的銀行系統
- 可以讓你寫到簡歷上的“網約車”專案,太讚了!!!
- git clone early EOF解決方法
- ES6(三) Promise 的基本使用方式
- Linux的哲學思想
- 為什麼阿里巴巴不建議 boolean 型別變數用 isXXX?
- 微信之夜,張小龍說視訊化表達將會成為下一個十年內容領域的主題
- WEB入門.九 導航選單
- 探索 .Net Core 的 SourceLink
- EdgeBERT:極限壓縮,比ALBERT再輕13倍!樹莓派上跑BERT的日子要來了? - 知乎
- shell 中if [ -e/d/f ..... ] 詳解
- 寫“好”程式碼的十九條準則
- 自學第三十五天
- 謝煙客---------二進位制安裝MariaDB,管理關係型資料庫的基本元件
- Egret之Sound壓縮方案
- Android studio 解決編譯速度慢 Download maven-metadata.xml速度很慢
- Flutter 中 BottomNavigationBar 定義底部導航條
- 肖四背背背
- nginx配置檔案
- yanghui三角形