什么是異步?
同步:一定要等任務執行完了,得到結果,才執行下一個任務。
異步:不等任務執行完,直接執行下一個任務。
為什么要用promise?
Promise的出現主要是解決地獄回調的問題,比如你需要結果需要請求很多個接口,這些接口的參數需要另外那個的接口返回的數據作為依賴,這樣就需要我們一層嵌套一層,但是有了Promise 我們就無需嵌套
Promise的本質就是分離了異步數據獲取和業務邏輯
$.Ajax()中的promise
如果不使用promise,$.ajax請求的時候成功和失敗的回調函數是寫在參數里的,他是對象參數的一個值
$.ajax({
method:"post", url:"/xxx", data:"username=mtt&password=1", dataType:'json', success:()=>{}//成功后的回調函數 error:()=>{}//失敗后的回調函數 } )
如果使用jQuery.axja()發送請求,並使用promise,代碼如下
let myButton = document.getElementById('myButton');
function success(responseText){
console.log("成功") console.log(responseText);//responseTex } function fail(request){ console.log("失敗") console.log(request); } myButton.addEventListener("click",(e)=>{ //使用ajax $.ajax({ method:"post", url:"/xxx", data:"username=mtt&password=1", dataType:'json'//預期服務器返回的數據類型,如果不寫,就是響應里設置的 } ).then(success,fail)//$.ajax()返回一個promise })
$.ajax()
函數會返回一個promise,然后在后面.then(success,fail)
時候,如果成功了就會調用第一個參數里的函數即success函數,如果失敗了就會調用第二個參數的函數即fail函數.
Promise的優點(1.語法上的簡化):不用記住失敗或者成功的函數名字.只需要知道成功是第一個參數,失敗時第二個參數,比如:
//使用ajax
$.ajax({
method:"post", url:"/xxx", data:"username=mtt&password=1", dataType:'json'//預期服務器返回的數據類型,如果不寫,就是響應里設置的 } ).then((responseText)=>{console.log(responseText)},()=>{console.log("失敗")})//$.ajax()返回一個promise,
Promise的優點(2.多次處理): .then(()=>{},()=>{})
$.ajax({
method:"post", url:"/xxx", data:"username=mtt&password=1", dataType:'json'//預期服務器返回的數據類型,如果不寫,就是響應里設置的 } ).then((responseText)=>{ console.log(responseText) return responseText;//如果要對結果進行多次處理,就在這里return,第二次then就會得到這個return的數據 },()=>{ console.log("失敗") }).then(//開始第二次then (上一次return的結果)=>{ console.log("第二次處理") console.log(上一次return的結果) }, ()=>{ //第二次處理失敗結果 } )
封裝一個類似$.Ajax()中的Promise的簡易版本
let ajax=function(url, param, type = 'POST'){ return new Promise(function(resolve, reject){ $.ajax({ type: type, url: url, data: param, dataType: 'json', success(res) { resolve(res) }, error(res) { reject('響應錯誤') // reject(res.statusText) } }) }) } // 使用示例 ajax('http://wh.xhd.cn/api/content/list.jspx',{channelIds: 1}).then(res=>{ console.log(res) })
///其他
//封裝ajax
window.jQuery.ajax = ({method,path,body,headers})=>{//ES6語法 //進行Promise封裝 return new Promise((resolve,reject)=>{//這句話是套路,記住 let request = new XMLHttpRequest(); request.open(method,path);//配置 for (const key in headers) {//遍歷header,設置響應頭 let value = headers[key]; request.setRequestHeader(key,value); } request.send(body);//發送,並配置響應體 request.onreadystatechange = ()=>{ if(request.readyState ===4){ if ( request.status>=200&&request.status<=400){ resolve.call(undefined,request.responseText);//執行成功函數 }else if(request.status>=400){ reject.call(undefined,request);//執行失敗函數 } } } }) }
//調用
myButton.addEventListener("click",(e)=>{ //使用ajax $.ajax({ method:"post", path:"/xxx", body:"username=mtt&password=1", headers:{ "content-type":'application/x-www-form-urlencoded', "mataotao":18 } }).then( (responseText)=>{console.log(responseText);},//成功就調用這個函數 (request)=>{console.log(request);}//失敗就調用這個函數 ) })
第一個要記住的:這個Promise
必須接收一個函數,函數里面就是要做的事情(即發送請求,Ajax請求),一般來說,把所有東西放在里面,第一句就是return
.然后要做的事情放在里面.
第二個要記住的:Promise接收的這個函數有兩個參數,一個叫做resolve
.一個叫reject
前兩個要記住的寫出來就是
return new Promise((resolve, reject) => { //要做的事 });
第三個要記住的:如果成功了就調一下resolve()
,如果失敗了就調用reject()
,所以Ajax()
參數中不需要successFn
和failFn
了 並且將成功行和失敗行對應的代碼分別改為 resolve.call(undefined,request.responseText);//執行成功函數
和reject.call(undefined,request);//執行失敗函數
上面是固定的套路
背下這個方法!!
function xxx(){
return new Promise((f1, f2) => { doSomething() setTimeout(()=>{ // 成功就調用 f1,失敗就調用 f2 },3000) }) } xxx().then(success, fail) // 鏈式操作 xxx().then(success, fail).then(success, fail)