Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >回调、使用Promise封装ajax()、Promise入门

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

作者头像
代码之风
发布于 2018-10-31 03:28:08
发布于 2018-10-31 03:28:08
3.4K00
代码可运行
举报
文章被收录于专栏:马涛涛的专栏马涛涛的专栏
运行总次数:0
代码可运行

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

1 回调是啥

call a function call a function back

callback

看这里: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.什么是异步?

[「每日一题」什么是异步?---方应杭知乎 ](https://zhuanlan.zhihu.com/p/... 下一篇博客再详细记录吧

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

「每日一题」Promise 是什么?

代码都在这里

3.1 $.Ajax()中的promise

如果不使用promise,$.ajax请求的时候成功和失败的回调函数是写在参数里的,他是对象参数的一个值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$.ajax({
        method:"post",
        url:"/xxx",
        data:"username=mtt&password=1",
        dataType:'json',
        success:()=>{}//成功后的回调函数
        error:()=>{}//失败后的回调函数
    }
    )

如果使用jQuery.axja()发送请求,并使用promise,代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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,不用记住函数名字.只需要知道成功是第一个参数,失败时第二个参数,比如这样写

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 //使用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的第二个意义

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$.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()代码核心部分:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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开始封装

封装之后的完整代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 前两个要记住的写出来就是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return new Promise((resolve, reject) => {
        //要做的事
    });

第三个要记住的:如果成功了就调一下resolve(),如果失败了就调用reject(),所以Ajax()参数中不需要successFnfailFn了 并且将成功行和失败行对应的代码分别改为 resolve.call(undefined,request.responseText);//执行成功函数reject.call(undefined,request);//执行失败函数

上面是固定的套路 封装完毕. 只分别修改了这几行代码

4.2如何调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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用法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function xxx(){
    return new Promise((f1, f2) => {
        doSomething()
        setTimeout(()=>{
            // 成功就调用 f1,失败就调用 f2
        },3000)
    })
}

xxx().then(success, fail)

// 链式操作
xxx().then(success, fail).then(success, fail)

十五行代码带你搞懂Promise - 浪子的文章 -知乎

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-08-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
33·灵魂前端工程师养成-[前后分离]异步与promise
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/10/31
9630
33·灵魂前端工程师养成-[前后分离]异步与promise
JS题目总结:原型链/new/json/MVC/Promise
解读: 上图中,Object,Function,Array,Boolean都是构造函数
代码之风
2018/10/31
1.1K0
Ajax设置请求和接收响应、自己封装简易jQuery.Ajax、回调函数
这篇文章是承接前几篇博客的,是前几篇继续学习 包括Ajax学习与理解和简化版自己实现jQuery等 这篇文章只算是我的个人学习笔记,内容没有精心排版,一些错误请见谅.
代码之风
2018/10/31
2.7K0
Promise接口实现之jQuery 的deferred对象
摘要总结:本文主要介绍了jQuery的Deferred对象和Promise对象,以及如何使用这些对象来实现异步编程和回调函数。同时,还介绍了一些常用的方法,如$.ajax、$.when等,并通过示例代码演示了如何使用这些方法来实现异步编程和回调函数。
IMWeb前端团队
2018/01/08
8590
ES6中的Promise和Fetch
JavaScript是单线程执行的,因此,为了避免操作时的页面中断(体现为页面假死),可以使用回调函数。但是如果回调函数中仍然嵌套有回调函数,代码就会变得越来越不可维护。这篇文章介绍ES6如何通过Promise解决这个问题,并介绍了相关的Fetch方法。
张子阳
2018/09/30
1.6K0
jQuery - Ajax详解分析(三)
回调函数 如果要处理 $.ajax() 得到的数据,则需要使用回调函数:beforeSend、error、dataFilter、success、complete。 beforeSend 在发送请求之前调用,并且传入一个 XMLHttpRequest 作为参数。 error 在请求出错时调用。传入 XMLHttpRequest 对象,描述错误类型的字符串以及一个异常对象(如果有的话) dataFilter 在请求成功之后调用。传入返回的数据以及 "dataType" 参数的值。并且必须返回新的数据(可能是处理过的)传递给 success 回调函数。 success 当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。 complete 当请求完成之后调用这个函数,无论成功或失败。传入 XMLHttpRequest 对象,以及一个包含成功或错误代码的字符串。
用户7718188
2021/10/07
3830
Promise对象
JavaScript是单线程的语言,通过维护执行栈与任务队列而实现了异步操作,setTimeout与Ajax就是典型的异步操作,Promise就是异步操作的一个解决方案,用于表示一个异步操作的最终完成或失败, 及其结果值,Promise有各种开源实现,在ES6中被统一规范,由浏览器直接支持。
WindRunnerMax
2020/08/27
6050
JavaScript 异步编程指南 — 你不知道的 Promise 前世 Deferred
这是一个系列文章,你可以关注公众号「五月君」订阅话题《JavaScript 异步编程指南》获取最新信息。
一只图雀
2021/06/17
1.1K0
JavaScript 异步编程指南 — 你不知道的 Promise 前世 Deferred
【ECMAScript6】es6 要点(二)Promise | 自个写一个Promise | Generator | Async/Await
但是,我们不能无限制地调用next从Generator实例中获取值。否则最后会返回undefined。原因:Generator犹如一种序列,一旦序列中的值被消费,你就不能再次消费它。即,序列为空后,再次调用就会返回undefined!。
前端修罗场
2023/10/07
3110
【ECMAScript6】es6 要点(二)Promise | 自个写一个Promise | Generator | Async/Await
ES6—new Promise()讲解,Promise对象是用来干嘛的?应该怎么用?使用场景有哪些?
复杂的概念先不讲,我们先简单粗暴地把Promise用一下,有个直观感受。那么第一个问题来了,Promise是什么玩意呢?是一个类?对象?数组?函数?
全栈程序员站长
2022/08/12
6.1K0
ES6—new Promise()讲解,Promise对象是用来干嘛的?应该怎么用?使用场景有哪些?
ES6之Promise
Promise JS是单线程的 就是同一个时间只能处理一个任务。就类似生活中的去超市排队结账,正常情况下,一位收银员只能为一位顾客结账,其他顾客需要在后面排队等候。 为什么 JS 是单线程的?作为浏览器脚本语言,JavaScript 的主要用途是与用户互动,以及操作 DOM 。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定 JavaScript同时有两个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准? 单线程就意味着,
19组清风
2021/11/15
7740
ES6之Promise
使用Promise封装一个 Ajax
首先, XMLHttpRequest (XHR)对象可以与服务器交互。你可以从URL获取数据,而无需让整个的页面刷新。这允许网页在不影响用户的操作的情况下更新页面的局部内容。在 Ajax 编程中 XMLHttpRequest 被大量使用。
钟俊耀
2019/08/26
2K0
使用Promise封装一个 Ajax
ajax和fetch、axios的优缺点以及比较
前端是个发展迅速的领域,前端请求自然也发展迅速,从原生的XHR到jquery ajax,再到现在的axios和fetch。
前端迷
2018/10/29
9.4K0
Promise是什么?Promise怎么使用?回调地狱[通俗易懂]
Promise是ES6提供的原生的类(构造函数), 用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作)
全栈程序员站长
2022/09/05
5700
Promise封装AJAX请求
AJAX(Asynchronous JavaScript and XML)是一种用于在后台与服务器进行异步数据交互的技术。它允许我们通过JavaScript发送HTTP请求,并在请求完成后处理响应数据,而无需刷新整个页面。
堕落飞鸟
2023/05/23
5220
JavaScript之Promise对象
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。
laixiangran
2018/07/25
8990
ES6-语法基础
箭头函数是把函数简写成一个表达式;如果只有一个参数,()可以省略;如果只有一个行,{ }可以省略,return 可以省略。
用户10175992
2022/11/15
4960
ES6-语法基础
Promise基础
为了避免同时使用同步、异步调用可能引起的混乱问题,Promise在规范上规定 Promise的then只能使用异步调用方式 。
elson
2020/01/02
4280
小程序不同页面的异步回调,callback和promise的使用讲解
我们这样写其实也没什么不对,但是如果数据请求和使用是在两个不同的页面呢。比如我们在app.js里请求位置,获取用户信息。然后在首页index.js里要使用这些数据,那么我们这么写就有问题了。下面就来教大家两种方式来很好的解决这个问题。
编程小石头
2020/10/11
1.6K0
JS中promise的基础用法
pormise在我看来,主要来优化存在多个ajax请求时,可以把回调函数给独立出来,统一调用。
小明爱学习
2020/07/03
4.1K0
相关推荐
33·灵魂前端工程师养成-[前后分离]异步与promise
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验