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 的优点:
- 简便地管理函数成功回调与失败回调
- 能够对函数返回结果进行多次处理(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、回调函数应用场景:
- 特定场景需求下,我们用定时器控制一个函数在指定时间后才会触发;
- 在发送 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