回调函数是函数的一种应用方式
在你调用 a 函数的时候, 把 b 函数当作参数传递进去
比如下面这种
getSend('./server/a.php', function (res) {
// res 就是后端发回来的响应体
var result = JSON.parse(res)
// 2. 发送第二个请求
getSend(`./server/b.php?n1=${result.n1}&n2=${result.n2}`, function (res2) {
var result2 = JSON.parse(res2)
console.log(result2)
// 3. 发送第三个请求
getSend(`./server/c.php?and=${result2.and}&n3=${result2.n3}`, function (res3) {
console.log(res3)
})
})
})
上面这个代码,虽然逻辑没有错,但是回调嵌套得太多,可读性和可维护性已经变得很低了.这还只是嵌套了三层,如果再多,基本上是写的人自己回头都看不明白干什么了.
我们可以利用promise对象来写,提高可读性.
function promiseGetSend(url){
let p=new Promise(function(resolve,reject){
//ajax步骤
let xhr=new XMLHttpRequest();
xhr.open('get',url);
xhr.onload=function(){
resolve(xhr.responseText);
}
xhr.send();
})
return p;
}
promiseGetSend('./a.php').then(function(res){
console.log(res);
let result=JSON.parse(res);
return promiseGetSend(`./b.php?n1=${result.n1}&n2=${result.n2}`);
}).then(function(res){
console.log(res);
return promiseGetSend(`./c.php?and=${res}&n3=8`);
}).then(function(res){
console.log(res);
})
promise对象使用的then函数,就是在第一个函数中的resolve(),是异步成功时执行的方法,只要前一个方法返回的是promise对象,就一直可以链式调用,程序就可以写的稍微好看一些了.
es7中新推出了async与await关键字,就是用来解决回调地狱的,这种方法的基础就是promise,不过可以写得再简单一些.
function promiseGetSend(url){
let p=new Promise(function(resolve,reject){
let xhr=new XMLHttpRequest();
xhr.open('get',url);
xhr.onload=function(){
resolve(xhr.responseText);
}
xhr.send();
});
return p;
}
async function a_p_g_s(){ //函数名字前加上async就会把这个函数变成一个异步函数
let a=await promiseGetSend('./a.php');//await就是将后面这个方法的执行结果返回给前面的变量a,
console.log(a);
let res=JSON.parse(a);
let b=await promiseGetSend(`./b.php?n1=${res.n1}&n2=${res.n2}`);
console.log(b);
let c=await promiseGetSend(`./c.php?and=${b}&n3=8`);
console.log(c);
}
a_p_g_s();
最后这三行,已经变得像普通的赋值表达式了,很清晰简单,维护肯定也很好维护了.
答应我,别给你的同事看地狱~ ~ ~ ~ ~
本文探讨了回调函数导致的‘回调地狱’问题及其对代码可读性和可维护性的负面影响。通过引入Promise对象,利用then方法进行链式调用来改善代码结构。进一步地,文章介绍了ES7中的async/await关键字,它基于Promise,使得异步代码更接近同步风格,提高了代码的可读性和易维护性。

被折叠的 条评论
为什么被折叠?



