资讯专栏INFORMATION COLUMN

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

godlong_X / 1207人阅读

摘要:回调使用封装入门回调是啥看这里回调是什么方应杭知乎是一种特殊的函数,这个函数被作为参数传给另一个函数去调用。

回调、使用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.什么是异步?

「每日一题」什么是异步?---方应杭知乎
下一篇博客再详细记录吧

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

「每日一题」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()参数中不需要successFnfailFn
并且将成功行和失败行对应的代码分别改为
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 - 浪子的文章 -知乎

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96734.html

相关文章

  • Promise必知必会

    摘要:而真正的回调函数,是在的外面被调用的,也就是和中调用方法返回的是一个新的实例注意,不是原来那个实例。 前端开发中经常会进行一些异步操作,常见的异步有: 网络请求:ajax IO操作: readFile 定时器:setTimeout 博客地址 回调 最基础的异步解决方案莫过于回调函数了 前端经常会在成功时和失败时分别注册回调函数 const req = new XMLHttpRequ...

    muzhuyu 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • ES6(一) —— 异步编程解决办法[从回调函数到promise,generator,async]

    摘要:回调函数这是最原始的一种异步解决方法。从的对象演化而来对象是提出的一种对异步编程的解决方案,但它不是新的语法,而是一种新的写法,允许将回调函数的嵌套改成链式调用。 一、前言 异步编程对JavaScript来说非常重要,因为JavaScript的语言环境是单线程的,如果没有异步编程将变得非常可怕,估计根本无法使用。这篇文章就来总结一下从最原始的回调函数到现在的ES6、ES7的新方法。 文...

    greatwhole 评论0 收藏0
  • ES6中Promise 承诺对象封装异步操作解析

    摘要:有了对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,对象提供统一的接口,使得控制异步操作更加容易。它的作用是为实例添加状态改变时的回调函数。这时,第二个方法指定的回调函数,就会等待这个新的对象状态发生变化。 Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。它由社区最早出和实现,ES6 将其写进了语言标准,统一了...

    qianfeng 评论0 收藏0

发表评论

0条评论

godlong_X

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<