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 连续调用流程不优雅的问题。

相关推荐
大怪v8 小时前
AI抢饭?前端佬:我要验牌!
前端·人工智能·程序员
新酱爱学习8 小时前
字节外包一年,我的技术成长之路
前端·程序员·年终总结
小兵张健8 小时前
开源 playwright-pool 会话池来了
前端·javascript·github
IT_陈寒11 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
codingWhat12 小时前
介绍一个手势识别库——AlloyFinger
前端·javascript·vue.js
代码老中医12 小时前
2026年CSS彻底疯了:这6个新特性让我删掉了三分之一JS代码
前端
不会敲代码112 小时前
Zustand:轻量级状态管理,从入门到实践
前端·typescript
踩着两条虫12 小时前
VTJ.PRO 双向代码转换原理揭秘
前端·vue.js·人工智能
扉川川12 小时前
OpenClaw 架构解析:一个生产级 AI Agent 是如何设计的
前端·人工智能
远山枫谷12 小时前
一文理清页面/组件通信与 Store 全局状态管理
前端·微信小程序