JavaScript的異步編程之Promise

Promise一種更優的異步編程統一 方法,如果直接使用傳統的回調函數去完成復雜操作就會形成回調深淵
// 回調深淵$.get('/url1'() => {$.get('/url2'() => {$.get('/url3'() => {$.get('/url4'() => {$.get('/url5'() => {// 大概就是這樣子的})})})})})CommonJS 社區提出了 Promise 規范,在ES2015中被標準化 , 成為語言規范 。當等待狀態改編程成功或者失敗之后就再也不能再被改變了 , 成功的時候觸發onFulfilled 回調,失敗的時候觸發onRejected 回調

JavaScript的異步編程之Promise

文章插圖
Promise 簡單使用new Promise 傳入一個回調函數,這個回調函數兩個參數,第一個把Promise 改成為成功的狀態,第二個參數把Promise改變成失敗的狀態,捕獲成功和異??梢允褂?code>.then和.catch方法 , 這兩個方法返回的也是一個Promise對象
// 演示const promsie = new Promise((resolve, reject) => {reject(1)})promsie.then((value) => {console.log(value)}, (err) => {// end 執行完之后才會執行這個console.log(err)})// end 會先執行console.log('end')不管Promise中有沒有異步操作,then方法中的回調函數依然會進入回調隊列中排隊,會等同步代碼執行完之后才會執行
Promise寫一個請求函數
function ajax (url) {return new Promise((resove, reject) => {var xhr = new XMLHttpRequest()xhr.open('GET', url)// 新方法可以直接接受一個j對象xhr.responseType = 'json'xhr.onload = function () {if (this.status === 200) {resove(this.response)} else {reject(new Error(this.statusText))}}xhr.send()})}ajax('/json1.json').then(ret => {console.log(ret)}).catch(err => {console.log(err)})如果需要多個連續的請求可以使用鏈式調用
ajax('/json1.json').then(ret => {return ajax('/json2.json')}).then(ret => {return ajax('/json3.json')}).then(ret => {return ajax('/json4.json')})這種鏈式調用是不是很熟悉,在jqeury中也有鏈式調用,jquery中是返回了本身這個對象所以可以實現鏈式調用,那么在Promise中是不是這樣呢
let promsie1 = ajax('/json1.json') let promise2 = promsie1.then(ret => {console.log(ret) }).catch(err => {console.log(err) }) console.log(promsie1 === promise2) // falselet a= $("body").attr('class', 'body')let b = a.prop('disabled', true)console.log(a === b) // true經過測試發現 , Promise返回的是一個全新的Promise對象,返回全新的Promise對象的目的就是為了實現Promise的鏈條,每個.then方法負責不同的任務,互不干擾,如果不斷的鏈式調用then方法,這里的每個then方法都在為上一個then方法返回的Promise對象去添加狀態明確后的回調 , 這些Promise會依次執行,而且我們可以在then方法中去手動返回一個Promise回調 。如果then方法中的回調函數返回了值,則會給下一個then方法的回調函數傳遞這個返回的值,如果沒有返回那么默認返回的就是undefined總結一下就是
  • Promise對象的then方法會返回一個全新的Promise對象
  • 后面的then方法就是在為上一個then返回的Promise注冊回調
  • 前面的then方法中的回調函數的返回值回作為后面then方法回調的參數
  • 如果回調中返回的是Promise, 那后面的then方法的回調會等待他的結束
捕獲異常onRejected 回調會在Promise執行異?;蛘邟伋龅漠惓r觸發, 捕獲異常有兩種方式,第一種, then(成功處理的回調函數, 異常處理的回調函數)then方法中傳遞兩個回調函數,第二種用.catch 方法去捕獲異常,catch方法其實就是then方法的別名,相當于then方法第一個參數傳undefined
// then(成功處理的回調函數, 異常處理的回調函數)ajax('/json1.json').then(ret => {console.log(err)}, err => {console.log(err)})// catchajax('/json1.json').then(ret => {console.log(err)}).catch(err => {console.log(err)})// catchajax('/json1.json').then(ret => {console.log(err)}).then(undefined,err => {console.log(err)})這兩種方式還是有很大的差異,catch 其實是在給上一個

推薦閱讀