解析Promise解決非同步回撥
Promise是ES6語法中新增的一個標準內建物件,它代表了一個非同步操作的最終完成或者失敗,能夠把非同步操作最終的成功返回值或者失敗原因和相應的處理函式關聯起來,是非同步“回撥地獄”的解決方案之一。
1 應用場景
要了解Promise物件,首先要了解這個物件的應用場景,Promise物件主要就是為瞭解決非同步回撥地獄問題的,那麼什麼是回撥函式呢?請看下面的一段程式碼:
// 定義一個函式a
function a(cb) {
cb()
}
// 定義一個函式b
function b() {
console.log('我是函式 b')
}
// 在函式a呼叫的時候,把函式b位置函式a的實參傳入
a(b)
此時,函式a和函式a的引數都是一個函式,為了便於區別,我們把作為函式a引數傳入的那個函式b叫做函式a的回撥函式,我們為什麼需要回撥函式?
當我們執行一個非同步的行為的時候,我們需要在一個非同步行為執行完畢之後做一些事情,那麼,我們是沒有辦法提前預知這個非同步行為是什麼時候完成的,我們就只能以回撥函式的形式來進行,比如我們需要透過ajax請求一個資料,根據ajax返回的結果執行不同的程式碼,但是我們不知道ajax物件什麼時候能獲取到返回結果,就需要使用回撥函式,看下面的程式碼:
// 定義data變數使用者儲存ajax獲取到的資料 let data = null;
// 執行ajax獲取資料的函式 function getData(){
let xhr = new XMLHttpRequest();
xhr.open('GET','/data.json');
// 監聽ajax的onload事件,事件觸發的時候就是請求完成的時候 xhr.onload = function(){
// 請求完成,ajax獲取到的資料賦值給data data = xhr.responseText;
}
xhr.send(null)
}
// ajax成功返回資料以後,根據返回的資料執行的程式碼 function showData(){
document.body.innerHTML = data;
}
getData();
showData();
如果採用上面的呼叫方式,先呼叫getData獲取資料以後直接呼叫showData顯示資料,那麼document.body.innerHTML = null,因為此時data還沒有獲取到資料,請求時非同步的,我們需要在請求完成的時候呼叫showData才行,也就是像下面這樣呼叫
// 定義data變數使用者儲存ajax獲取到的資料 let data = null;
// 執行ajax獲取資料的函式 function getData(cb){
let xhr = new XMLHttpRequest();
xhr.open('GET','/data.json');
// 監聽ajax的onload事件,事件觸發的時候就是請求完成的時候 xhr.onload = function(){
// 請求完成,ajax獲取到的資料賦值給data data = xhr.responseText;
// 之後再呼叫傳入的showData函式 cb();
}
xhr.send(null)
}
// ajax成功返回資料以後,根據返回的資料執行的程式碼 function showData(){
document.body.innerHTML = data;
}
getData(showData);
2 回撥地獄
當一個回撥函式巢狀一個回撥函式的時候,就會出現一個巢狀結構,當巢狀的多了就會出現回撥地獄的情況, 比如我們傳送三個 ajax 請求,第一個正常傳送,第二個請求需要第一個請求的結果中的某一個值作為引數,第三個請求需要第二個請求的結果中的某一個值作為引數
ajax({
url: '我是第一個請求',
success (res) {
// 現在傳送第二個請求 ajax({
url: '我是第二個請求',
data: { a: res.a, b: res.b },
success (res2) {
// 進行第三個請求 ajax({
url: '我是第三個請求',
data: { a: res2.a, b: res2.b },
success (res3) {
console.log(res3) ;
// ... }
})
}
})
}
})
回撥地獄,其實就是回撥函式巢狀過多導致的,當程式碼成為這個結構以後,已經沒有維護的可能了,所以我們要把程式碼寫的更加的藝術一些。
3 Promise的使用
Promise是一個物件,這個物件有三個狀態:
- 待定(pending):初始狀態,既沒有成功,也沒有失敗,表示非同步任務正在進行中
- 成功(fulfilled):非同步任務執行完畢,變成成功狀態
- 失敗(rejected):非同步任務執行完畢,變成失敗狀態
下面就帶大家建立一個Promise物件
let p1 = new Promise(function (resolve, reject) {
// 此處執行非同步的程式碼 setTimeout(()=>{
// 我們可以根據自己的標準在非同步任務完成的時候 // 選擇是執行失敗的回撥函式還是成功的回撥函式 // 第一個形參resolve 表示成功的回撥 resolve('300')
// 第二個形參reject 表示失敗的回撥 },3000)})// 定義當p1這個promise物件變成成功狀態的時候要執行的回撥函式p1.then((data)=>{
console.log("我是成功的時候執行的函式")
console.log("我執行的時候你給我傳入的引數",data)})// 定義當p1這個promise物件變成失敗狀態的時候要執行的回撥函式p1.catch((err)=>{
console.log("我是失敗的時候執行的函式")
console.log("我執行的時候你給我傳入的引數",err)})
Promise物件這樣就建立好了,那小夥伴們趕緊自己試試吧!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023145/viewspace-2940164/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- promise解決回撥地獄;啥?前端還有“地獄?”Promise前端
- 好程式設計師web前端教程分享怎麼用promise解決回撥和非同步程式設計師Web前端Promise非同步
- java回撥函式-非同步回撥-簡明講解Java函式非同步
- 非同步/回撥非同步
- jQuery原始碼剖析(四) - Deferred非同步回撥解決方案jQuery原始碼非同步
- 用Promise建構函式來解決地獄回撥問題Promise函式
- 非同步解決方案---promise非同步Promise
- ES6 Promise 應用: 回撥函式方法封裝成 Promise + async/await 同步化Promise函式封裝AI
- C++屌屌的觀察者模式-同步回撥和非同步回撥C++模式非同步
- JavaScript非同步程式設計史:回撥函式到Promise到Async/AwaitJavaScript非同步程式設計函式PromiseAI
- 【真知拙見】回撥地獄和PromisePromise
- 小程式點睛之一:如何將小程式非同步回撥介面 Promise 化非同步Promise
- Android BLE & BluetoothGattCallback.onServicesDiscovered不回撥或部分回撥解決Android
- 非同步解決方案----Promise與Await非同步PromiseAI
- javascript非同步解決方案之promiseJavaScript非同步Promise
- 非同步解決方案—-Promise與Await非同步PromiseAI
- 簡單粗暴的去重promise的回撥Promise
- 回撥函式到promise再到理解async/await函式PromiseAI
- javascript非同步回撥是什麼JavaScript非同步
- 【設計模式】非同步阻塞、非同步回撥模式設計模式非同步
- 小技巧:使用Array.reduce建立Promise回撥鏈Promise
- Javascript回撥非同步操作示例教程JavaScript非同步
- ActiveMQ-MessageListener非同步回撥處理MQ非同步
- 手把手教你Node使用Promise替代回撥函式Promise函式
- C# 同步 非同步 回撥 狀態機 async await DemoC#非同步AI
- 回撥地獄-編寫非同步JavaScript指南非同步JavaScript
- Flutter Future 回撥地獄的一種解決思路Flutter
- promise-java非同步程式設計解決方案PromiseJava非同步程式設計
- 用匿名內部類實現 Java 同步回撥Java
- arcgis api for js回撥函式如何等待同步APIJS函式
- iOS-微博登入回撥不成功的解決iOS
- JS 非同步發展流程(回撥函式=>Async/await)JS非同步函式AI
- Swift 中如何利用閉包實現非同步回撥?Swift非同步
- [JS]回撥函式和回撥地獄JS函式
- 回撥方法
- 基於Guava API實現非同步通知和事件回撥GuavaAPI非同步事件
- JavaScript 非同步操作裡的巢狀回撥函式JavaScript非同步巢狀函式
- Promise相關內容(三)——非同步獲取伺服器資料:promise方式解決回撥地獄的問題。通過多個.then使程式碼可讀性更高 & 解決非同步任務的序列執行,保證按順序傳送請求獲取資料Promise非同步伺服器