promise 简单封装 ajax 解决回调地狱

promise 简单封装 ajax 解决回调地狱

一个页面会有许多的 ajax 请求,要怎么管理好这些请求的调用顺序,防止请求的不断嵌套造成回调地狱呢?这个时候就用的上 Promise了。

1、何为 ajax 请求?

ajax 是异步的 javascript和 xml。简单点说,就是使用 XMLHttpRequest 对象与服务器通信。

以 jquery 的 ajax 为例:

$.ajax({
        method:"post",
        url:"/lin/test",
        data:"username=mtt&password=1",
        dataType:'json',
        success:()=>{}//成功后的回调函数
        error:()=>{}//失败后的回调函数
 })

通过 ajax 我们可以与向服务器发送及接收数据,实现与服务器的通信。

2、promise 封装 ajax

promise 是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。

想了解更多关于 promise 的内容请点击这里

封装 ajax 的优点:

  1. 简便地管理函数成功回调与失败回调
  2. 能够对函数返回结果进行多次处理(then嵌套)

一个函数,返回 promise 的模板大致如下:

test() {
    return new Promise((resolve, reject) => {
        //要做的事
    });
}

将函数里的 ajax 简单封装成 promise,则如下:

test(data) {
    return new Promise((resolve, reject) => {
        $.ajax({
        method:"post",
        url:"/lin/test",
        data:"username=mtt&password="+ data,
        dataType:'json',
        success:(data)=>{
            resolve(result);
        }
        error:(exception)=>{
            reject(exception)
 		})
    });
}

上面完成了对 ajax 的封装,调用函数会返回 promise, 通过 then() 对请求结果进行处理:

test(data).then((result) => successHandle(), (exception) => errorHandle);

封装后的 ajax() 返回一个 new 出来的 promise 对象,这个 promise 实例有一个 then 属性,他是一个函数,所以可以调用 then().而且 then 也会返回一个promise对象。

3、 何为回调地狱?

3.1、先说明什么是回调函数:

把一个函数当作参数传递,传递的是函数的定义并不会立即执行,而是在将来特定的时机再去调用,这个函数就叫做回调函数。

3.2、回调函数应用场景:

  1. 特定场景需求下,我们用定时器控制一个函数在指定时间后才会触发;
  2. 在发送 ajax 中,客户端和服务器之间的请求和响应都是需要时间的,而我们要拿响应回来的数据就必须等响应完成,这些都是回调函数的常用场景。

3.3、回调地狱

理解了回调函数,那么回调地狱就很容易理解了,简单来说就是回调函数的嵌套

const fn = (str, callback) => {
    setTimeout(() => {
        console.log(str)
        callback(str)
    }, 100);
}

fn('1', () => {
    fn('2', () => {
        fn('3', () => {
            fn('4', () => {
                console.log('done')
            })
        })
    })
})

4、promise 链式调用解决回调地狱

回调地狱的需求是为了保证函数的正确执行顺序,promise 的 then 属性包含对函数执行结果的成功与失败回调,那么我们通过 then 属性来代替原来的回调函数就可以了, 以上文的 test() 函数为例子:

test(data)
	.then(() => test1(data1))
	.then(() => test2(data2))
	.then(() => test3(data3)

这就是 promise 的链式调用,能够保证函数的执行顺序为 test() -> test1() -> test2() -> test3(),解决回调地狱的问题。

参考资料:

https://juejin.cn/post/7065129481513467941

https://blog.csdn.net/qq_42805569/article/details/110404566

https://segmentfault.com/a/1190000015938472

posted @ 2022-04-29 16:41  MyDistance  阅读(589)  评论(0编辑  收藏  举报