是的。promise是ECMAScript 6新增的引用類型,表示一個異步操作的最終完成或者失敗。promise是解決異步編程調用代碼邏輯編寫過于復雜的問題的,當網絡請求非常復雜時,就會出現回調地獄,這樣如果將這些代碼寫在一起就會看起來很復雜,且不利于閱讀,如果用promise的話就會讓代碼看起來更加美觀優雅。
前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調試工具:點擊使用
本教程操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。
ECMAScript 6 增加了對 Promises/A+ 規范的完善支持,即 Promise 類型。一經推出,Promise 就大受歡迎,成為了主導性的異步編程機制。所有現代瀏覽器都支持 ES6 期約,很多其他瀏覽器 API 也以期約為基礎。
Promise 是 ECMAScript 6 新增的引用類型,表示一個異步操作的最終完成或者失敗。
一、promise函數是干什么的
promise函數是解決異步編程調用代碼邏輯編寫過于復雜的問題的,當網絡請求非常復雜時,就會出現回調地獄,這樣如果將這些代碼寫在一起就會看起來很復雜,且不利于閱讀,如果用promise的話就會讓代碼看起來更加美觀優雅
二、Promise三種狀態
首先, 當我們開發中有異步操作時, 就可以給異步操作包裝一個Promise
異步操作之后會有三種狀態
pending:等待狀態,比如正在進行網絡請求,或者定時器沒有到時間。 fulfill:滿足狀態,當我們主動回調了resolve時,就處于該狀態,并且會回調.then() reject:拒絕狀態,當我們主動回調了reject時,就處于該狀態,并且會回調.catch()
三、實現
1,then和catch
1.出于未決狀態的函數是同步的 會立即執行
2.then和catch是異步的 就算promise對象里面沒有異步操作 讓then方法或者catch立即執行 那么 這里兩個方法或被加入到事件隊列中等待執行
//參數 函數(resolve,reject) new Promise((resolve, reject) => { setTimeout(() => { //請求成功的時候調用resolve resolve('22222') //請求失敗的時候調用reject reject('error message') }, 1000) }).then((data) => { //請求成功處理函數 console.log(data) }).catch((err) => { //請求失敗處理函數 console.log(err) })
2.確定狀態
1、在未決狀態的處理函數中 如果發生未捕獲的錯誤呀 那么狀態就會有pending 直接變成 rejected狀態 并且可以被catach捕獲
var pro = new Promise((resolve, reject) => { throw new Error("123"); // try{ // throw new Error("123"); // } catch(e) {} resolve(12); reject(34); }) // pro.then(data => { // console.log(data); // }, err => { // console.log(err); // }) console.log(pro); pro.then(data => { console.log(data); }) pro.catch(data => { console.log(data); })
3.async和await
1.使用Promise:
const makeRequest = () => getJSON().then(data => { console.log(data) return "done" }) makeRequest()
2.使用Async:
async和await 是ES7提出來的
async作用:簡化函數返回值中promise對象的創建
一般情況下, async寫在函數的最前面,被修飾的函數的返回值 ,一定是promise對象。只有在某些特殊情況下 才會手動返回一個promise對象。
作用:和promise一樣 解決異步問題 但是他的好處在于 讓異步代碼和同步的一樣!!
注意點 : 同步方法我們拿到結果 是通過返回值,異步方法拿到結果,是靠回調函數。
async 和await使用的基本語法 :
-
就是在普通函數前面加一個async 調用跟普通函數一樣
-
async出現使用 一般都要和await配合使用
-
await后面接的就是一個promise對象 await一定是在異步函數中使用的
const makeRequest = async () => { // await getJSON()表示console.log會等到getJSON的promise成功reosolve之后再執行。 console.log(await getJSON) return "done" } makeRequest()
3.區別
1.函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串”done”)
2.我們不能在最外層代碼中使用await,因為不在async函數內。
四.promise方法
var r1 = new Promise((resolve,reject) => { setTimeout(function(){ resolve("我是第一個請求"); },1000) }) var r2 = new Promise((resolve,reject) => { setTimeout(function(){ resolve("我是第二個請求"); },3000) }) var r3 = new Promise((resolve,reject) => { setTimeout(function(){ resolve("我是第三個請求"); },4000) }) var r4 = new Promise((resolve,reject) => { setTimeout(function(){ resolve("我是第四個請求"); },500) })
1.all方法
有時候我們需要等待兩個或者多個請求都成功返回了再進行下一步操作,promise 的all方法是等所有的異步請求完成之后在進行下一步回調
Promise.all([r1,r2,r3,r4]).then(data => { console.log(data); })
2.race方法
請求同時發送出去 誰先回來 就是用誰的數據。
Promise.race([r1,r2,r3,r4]).then(data => { console.log(data); })
五.promise封裝ajax案例
<script> function toData(obj) { // 聲明一個數組 來裝每一組的數據 var arr = []; if(obj !== null) { for(var key in obj) { let str = key + "=" + obj[key]; arr.push(str); } return arr.join("&"); } } function ajax(obj) { return new Promise(function(resolve, reject) { // 給ajax所需要的參數設置默認值 obj.type = obj.type || "get"; obj.async = obj.async|| "true"; obj.dataType = obj.dataType || "json"; obj.data = obj.data || null; // 開始發送ajax請求 var xhr; if(window.XMLHttpRequest) { xhr = new XMLHttpRequest(); } else { // IE低版本的瀏覽器 xhr = new ActiveXObject("Microsoft.XMLHttp"); } // 判斷是post請求 還是get請求 if(obj.type === "post") { xhr.open(obj.type, obj.url, obj.async); // 設置請求頭 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(toData(obj.data)); } else { var url = obj.url + "?" + toData(obj.data); xhr.open(obj.type, url, obj.async); xhr.send(); } // 處理響應體 xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) { resolve(JSON.parse(xhr.responseText)); } else { reject(xhr.status); } } } }) } ajax({ url : "./data.php", data : { name : "jack", age : 16 } }).then(res => { console.log(res); }, err => { console.log(err); }) </script>
【