Promise 优化 Ajax

Ajax 请求是前端使用频率最高的功能之一,虽然现在有各种各样的工具库能够实现快速简洁的调用 Ajax 接口,但是在一些特定项目中,我们可能就是需要使用原生 Ajax 来发送请求。

今天我们就来尝试着使用 Promise 封装一下原生 Ajax,改善其回调冗长的问题。

封装

封装的主要思路就是:

  • 如果成功响应,则通过调用 resolve 结束 promise
  • 如果响应失败,则通过调用 reject 结束 promise
js 复制代码
function myAjax(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                if (this.status == 200) {
                    // 成功的回调
                    resolve(this.responseText)
                } else {
                    // 失败的回调
                    reject(new Error());
                }
            }
        }

        xhr.open('get', url)
        xhr.send();
    })
}

这里要注意一个问题,如果返回的结果中,又有 ajax 请求需要发送,可一定记得使用链式调用,不要在then中直接发起下一次请求,否则,又是地狱见了:

js 复制代码
 //  ==== Promise 误区====
myAjax('./d1.json').then(data=>{
    console.log(data);
    myAjax('./d2.json').then(data=>{
        console.log(data)
        // ......回调地狱......
    })
})

链式的意思就是在上一次 then 中,返回下一次调用的 Promise 对象,我们的代码,就不会进地狱了;

js 复制代码
myAjax('./d1.json')
    .then(data=>{
    console.log(data);
    return myAjax('./d2.json')
})
    .then(data=>{
    console.log(data)
    return myAjax('./d3.json')
})
    .then(data=>{
    console.log(data);
})
    .catch(err=>{
    console.log(err);
})

优化

Promise 的最大问题是代码冗余,原来的任务被 Promise 包装了一下,不管什么操作,一眼看去都是一堆 then,原来的语义变得很不清楚。

我们可以继续使用Async/Await 优化 Ajax 调用的过程。

将整个调用 Ajax 的流程封装成一个 async 函数,在其内部通过 await 控制 ajax 的执行顺序:

js 复制代码
 async function callAjax(){
     var a = await myAjax('./d1.json')
     console.log(a);
     var b = await myAjax('./d2.json');
     console.log(b)
     var c = await myAjax('./d3.json');
     console.log(c)
 }
callAjax();

注意:await 关键词 只能在 async 函数内部使用

总结

本文使用了 Promise+Async/await优化了原生 Ajax 连续调用流程不优雅的问题。

相关推荐
mCell10 小时前
使用 useSearchParams 同步 URL 和查询参数
前端·javascript·react.js
mCell12 小时前
前端路由详解:Hash vs History
前端·javascript·vue-router
海上彼尚12 小时前
无需绑卡的海外地图
前端·javascript·vue.js·node.js
1024肥宅12 小时前
手写 call、apply、bind 的实现
前端·javascript·ecmascript 6
科杰智能制造13 小时前
纯前端html、js实现人脸检测和表情检测,可直接在浏览器使用
前端·javascript·html
每天吃饭的羊13 小时前
组件库的有些点击事件是name-click这是如何分装de
前端·javascript·vue.js
x***010613 小时前
SpringSecurity+jwt实现权限认证功能
android·前端·后端
1024肥宅13 小时前
防抖(Debounce)
前端·javascript·ecmascript 6
1024肥宅13 小时前
节流(Throttle)
前端·javascript·ecmascript 6
by__csdn13 小时前
Vue2纯前端图形验证码实现详解+源码
前端·javascript·typescript·vue·状态模式·css3·canva可画