call a function
call a function backgit
callbackgithub
看这里:Callback(回调)是什么?---方应杭知乎ajax
callback 是一种特殊的函数, 这个函数被做为参数传给另外一个函数去调用。这样的函数就是回调函数。
Callback 很常见$button.on('click', function(){})
click后面的 function 就是一个回调,由于「我」没有调用过这个函数,是 jQuery 在用户点击 button 时调用的(当用户点击以后,这个函数才执行,如今我只是传了一个参数,这个参数是一个点击后要执行的函数)。json
div.addEventListener('click', function(){})
click 后面的 function 也是一个回调,由于「我」没有调用过这个函数,是浏览器在用户点击 button 时调用的。segmentfault
通常来讲,只要参数是一个函数,那么这个函数就是回调。promise
请看我写的封装的简易jQuery.ajax()中的successFN
就是一个回调函数.浏览器
只有在请求成功并接收到响应的时候才会执行这个success函数,这就是回调.传一个函数做为参数可是不执行,让另外一个函数去调用,就是回调函数服务器
callback 有一点「反直觉」。
好比说咱们用代码作一件事情,分为两步:step1( ) 和 step2( )。app
符合人类直觉的代码是:异步
step1()
step2()
callback 的写法倒是这样的:
step1(step2)
为何要这样写?或者说在什么状况下应该用这个「反直觉」的写法?
通常(注意我说了通常),在 step1 是一个异步任务的时候,就会使用 callback。
什么是异步任务呢?
「每日一题」什么是异步?---方应杭知乎
下一篇博客再详细记录吧
若是不使用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的第一个意义:不用记住成功和失败究竟是success,仍是successFN或者是fail或者是error,不用记住函数名字.只须要知道成功是第一个参数,失败时第二个参数,好比这样写
//使用ajax $.ajax({ method:"post", url:"/xxx", data:"username=mtt&password=1", dataType:'json'//预期服务器返回的数据类型,若是不写,就是响应里设置的 } ).then((responseText)=>{console.log(responseText)},()=>{console.log("失败")})//$.ajax()返回一个promise
彻底不须要写函数名
若是你须要对一个结果进行屡次处理,能够这样写:
$.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的结果) }, ()=>{ //第二次处理失败结果 } )
结果:
看到第二个then里的函数吧第一次then里return的结果当作参数,继续处理.
因此promise的好处是若是想再次用两个函数,即再次对结果进行处理,就再then 一下,不须要再次取名字了
then的中文含义:而后!
以上就是ajax中promise的简单使用,那么如何本身封装一个呢?
PS:ajax()
函数参数里的dataType:'json'//预期服务器返回的数据类型,若是不写,就是响应里设置的
即:
ajax方法中的dataType:预期服务器返回的数据类型。若是不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断。
接下来回到咱们本身封装的jQuery.Ajax()代码.咱们以此为基础继续来封装promise
之前封装的代码在这里
也能够看我前一篇博客,里面有如何封装Ajax()的方法和详细过程.
原来的封装Ajax()代码核心部分:
window.jQuery.ajax = ({method,path,body,successFn,failFn,headers})=>{//ES6语法 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){ successFn.call(undefined,request.responseText);//执行成功函数 }else if(request.status>=400){ failFn.call(undefined,request);//执行失败函数 } } } }
封装以后的完整代码
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);//执行失败函数 } } } }) }
return
一个new Promise()
.
第一个要记住的:这个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);//执行失败函数
上面是固定的套路
封装完毕.
只分别修改了这几行代码
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);}//失败就调用这个函数 ) })
在ajax()
函数后接上.then()
,成功就调用then()
函数第一个参数里的函数,失败就调用then()
函数第二个参数里的函数
简单的Promise原理:
本身封装后的Ajax()返回一个new出来的 Promise对象,一个Promise实例,这个Promise实例有一个then属性,他是一个函数,因此能够调用then().并且then也会返回一个Promise对象.
Promise接收一个函数,这个函数就是你要作的事情
因此Promise本质上只是规定一种形式!
请背下这个代码
Promise用法
function xxx(){ return new Promise((f1, f2) => { doSomething() setTimeout(()=>{ // 成功就调用 f1,失败就调用 f2 },3000) }) } xxx().then(success, fail) // 链式操做 xxx().then(success, fail).then(success, fail)