回调、使用Promise封装ajax()、Promise入门

1 回调是啥

call a function

call a function back

callback

callback 是一种特殊的函数,这个函数被作为参数传给另一个函数去调用。这样的函数就是回调函数。

1.1 回调例子

Callback 很常见

$button.on('click', function(){})

click后面的 function 就是一个回调,因为「我」没有调用过这个函数,是 jQuery 在用户点击 button 时调用的(当用户点击之后,这个函数才执行,现在我只是传了一个参数,这个参数是一个点击后要执行的函数)。

div.addEventListener('click', function(){})

click 后面的 function 也是一个回调,因为「我」没有调用过这个函数,是浏览器在用户点击 button 时调用的。

一般来说,只要参数是一个函数,那么这个函数就是回调。

请看我写的封装的简易jQuery.ajax()中的successFN就是一个回调函数.

只有在请求成功并接收到响应的时候才会执行这个success函数,这就是回调.传一个函数作为参数但是不执行,让另一个函数去调用,就是回调函数

1.2Callback 有点反直觉

callback 有一点「反直觉」。

比如说我们用代码做一件事情,分为两步:step1( ) 和 step2( )。

符合人类直觉的代码是:

step1()

step2()

callback 的写法却是这样的:

step1(step2)

为什么要这样写?或者说在什么情况下应该用这个「反直觉」的写法?

一般(注意我说了一般),在 step1 是一个异步任务的时候,就会使用 callback。

什么是异步任务呢?

2.什么是异步?

3. $.Ajax()Promise 是什么?如何用?

3.1 $.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

})

成功的结果:

换一个不存在的地址/mtt失败的结果

$.ajax()函数会返回一个promise,然后在后面.then(success,fail)时候,如果成功了就会调用第一个参数里的函数即success函数,如果失败了就会调用第二个参数的函数即fail函数.

3.1.1 promise的第一个意义

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

完全不需要写函数名

3.1.2promise的第二个意义

如果你需要对一个结果进行多次处理,可以这样写:

$.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 信息来智能判断。

4封装一个类似$.Ajax()中的Promise的简易版本(皮毛,以后深入)

接下来回到我们自己封装的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);//执行失败函数

}

}

}

}

4.1开始封装

封装之后的完整代码

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);//执行失败函数

上面是固定的套路

封装完毕.

只分别修改了这几行代码

4.2如何调用

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本质上只是规定一种形式!

5 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)

用promise封装ajax_回调、使用Promise封装ajax()、Promise入门相关推荐

  1. ajax地址为jsp,AJAX_在jsp中运用ajax(简单入门),由于ajax为我们带来太多的好处 - phpStudy...

    在jsp中运用ajax(简单入门) 由于ajax为我们带来太多的好处,所以在很多应用中我们都会优先选择这种技术,于是我也为之所吸引,现跟大家分享下一个简单的入门例子. regist.jsp文件:一个简 ...

  2. Promise学习——解决回调地狱问题

    Promise promise 容器概念: callback hell(回调地狱): 文件的读取无法判断执行顺序(文件的执行顺序是依据文件的大小来决定的)(异步api无法保证文件的执行顺序) var ...

  3. promise对象-代替回调函解决异步操作

    问题: 服务器中有3个文件a.txt.b.txt.c.txt分别存储的数据为1.2.3,通过js中的异步ajax,分别获取这3个文件的内容并求和输出6. 问题答案方法一(回调函数方法):(对应下面的: ...

  4. Promise语法处理回调地狱

    一.什么是回调地狱 setTimeout(function () { //第一层console.log(111);setTimeout(function () { //第二程console.log(2 ...

  5. node.js学习笔记Day8:关于回调地狱和其解决方案Promise的几个应用和理解。

    9.promise(异步编程) 9.1回调地狱: 由于异步性,程序并不会等待之前一个响应结束.也即下面的这样一个代码,对三个文件的读取顺序并没有保证,可能有时abc的顺序,有时cba.. var fs ...

  6. 使用fetch封装ajax_如何使用Fetch在JavaScript中进行AJAX调用

    使用fetch封装ajax I will be sharing bite sized learnings about JavaScript regularly in this series. We'l ...

  7. 使用ES6的Promise完美解决回调地狱

    相信经常使用ajax的前端小伙伴,都会遇到这样的困境:一个接口的参数会需要使用另一个接口获取. 年轻的前端可能会用同步去解决(笑~),因为我也这么干过,但是极度影响性能和用户体验. 正常的前端会把接口 ...

  8. Promise相关内容(三)——异步获取服务器数据:promise方式解决回调地狱的问题。通过多个.then使代码可读性更高 实现异步任务的串行执行,保证按顺序发送请求获取数据

    Promise相关内容(三)--异步获取服务器数据:promise方式解决回调地狱的问题.通过多个.then使代码可读性更高 & 实现异步任务的串行执行,保证按顺序发送请求获取数据 第一种形式 ...

  9. promise then err_Promise 原理解析与实现(遵循Promise/A+规范)

    1什么是Promise? Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一 2对于几种常见异步编程方案 回调函数 事件监听 发布/订阅 ...

  10. Promise的源码实现(完美符合Promise/A+规范)

    Promise是前端面试中的高频问题,我作为面试官的时候,问Promise的概率超过90%,据我所知,大多数公司,都会问一些关于Promise的问题.如果你能根据PromiseA+的规范,写出符合规范 ...

最新文章

  1. 第3周 区_SQL Server中管理空间的基本单位
  2. 007_JMS中的持久订阅
  3. Android--OkHttp理解系列(一)
  4. 穷人迈向富翁的理财十步曲
  5. 1218数据库操作工具类的使用
  6. HTML textarea控件
  7. IAR下STM32进入HardFault_Handler
  8. Puzzle——模拟
  9. QQ第三方授权登录(带详细源码)
  10. SQL2K数据库开发七之表操作添加删除和修改列
  11. python 下载bilibili视频
  12. mybatis学习笔记(10)-一对一查询
  13. DECLARE_DYNAMIC IMPLEMENT_DYNAMIC
  14. ipixsoft swf to html5 converter,iPixSoft SWF to Video Converter
  15. 机器学习——马氏距离
  16. 计划三年投入十亿资金,统信UOS生态腾飞加速
  17. 【11】processing-曲线(中文)
  18. 407. 接雨水 II【我亦无他唯手熟尔】
  19. 金三银四想跳槽的,要抓紧时间补补了
  20. 计算机网络技术毕业生实习报告_计算机网络专业实习报告

热门文章

  1. Remoting PerfMon Service
  2. [JWF]使用脚本访问ActiveDirectory(二)GetObject()
  3. 日志分析工具 GoAccess v1.3 发布,支持简体中文和安装使用
  4. 发送HTTP请求返回415状态码的解决办法
  5. SQLserver C#将图片以二进制方式存储到数据库,再从数据库读出图片
  6. 全网首发:Undefined symbols for architecture x86_64: “std::__1::locale::use_facet(std::__1::locale::id)
  7. 管理新语:如果经验有用,大家都去养老院招人了
  8. nvinfer1::cudnn::Engine::deserialize()出错的原因
  9. 万恶的WIN10,已有的VirftualBox虚拟机都不能用了
  10. fatal error: gnu/stubs-n64_hard_2008.h: No such file or directory