回调地狱
什么是回调地狱,回调函数,一个嵌套着一个,到最后,缩略图成了 一个三角形, 造成了可阅读性差,可阅读性差就代表代码的可维护性 和 可迭代性差,最后还有一个就是可扩展性差。
也不符合设计模式的六大原则, 其中的 单一职责原则, 和 开闭原则
单一职责原则: 尽量让一个函数只做一件事情
开闭原则:函数应该对扩展开放,对修改关闭
接下来看一下什么是回调地狱:
小案例的效果图:
下面的代码虽然能实现这个功能,但是如果按照这种做法,功能一多,回调函数会一个嵌套一个, 最后的代码会形成一个三角区。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 * { 10 padding: 0px; 11 margin: 0px; 12 } 13 14 .tpl { 15 display: none; 16 } 17 18 .wrapper { 19 overflow: hidden; 20 border: 2px solid black; 21 width: 600px; 22 margin: 100px auto 0px; 23 } 24 .movieSection { 25 float: left; 26 width: 180px; 27 height: 180px; 28 padding: 10px; 29 } 30 31 .movieSection img { 32 width: 100%; 33 height: 150px; 34 cursor: pointer; 35 } 36 37 .movieSection h3 { 38 height: 30px; 39 } 40 </style> 41 </head> 42 <body> 43 <!-- 基本结构 --> 44 <div class="wrapper"> 45 <div class='tpl'> 46 <img src=""></img> 47 <h3 class='movieName'></h3> 48 </div> 49 </div> 50 51 <script src='./jquery.js'></script> 52 <script> 53 $.ajax({ 54 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', 55 type: 'POST', 56 data: { 57 username: 'fsfs', 58 password: '123123' 59 }, 60 success: function (res) { //一个回调函数,解决了全部事情,因为下面的代码 都是在这个回调里面。 61 if (res.data.power == 'root') { 62 $.ajax({ //如果账号密码正确, 执行 success 回调 请求数据 63 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList', 64 type: 'GET', 65 success: function (res) { //如果 请求成功, 执行回调以下拿到数据渲染 页面 66 console.log(res) 67 var data = res.data; 68 var $Wrapper = $('.wrapper'); 69 $.each(data, function(index, ele) { 70 var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection'); 71 $MovieSection.data({id: ele.id}).on('click', function (){//添加点击事件 再次请求 详细文字页面 72 73 $.ajax({ 74 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo', 75 type: 'GET', 76 data: { 77 movieId: $(this).data('id') 78 }, 79 success: function (res) { //如果请求数据成功,执行回调再次添加 数据到页面 80 var data = res.data; 81 var direct = data.direct; 82 var gut = data.gut; 83 var mainActor = data.mainActor; 84 var screenWriter = data.screenwriter; 85 86 var htmlStr = '<div class="mask"> 87 <p>导演: ' + direct + '</p> 88 <p>剧情: ' + gut + '</p> 89 <p>主演: ' + mainActor.reduce(function (prev, curv) { 90 prev += curv + ' '; 91 return prev; 92 }, '') + '</p> 93 <p>编剧: ' + screenWriter.reduce(function (prev, curv) { 94 prev += curv + ' '; 95 return prev; 96 }, '') + '</p> 97 </div>' 98 99 $(htmlStr).appendTo('body') 100 101 } 102 }); 103 }).children() 104 .eq(0).attr('src', ele.poster) 105 .next().text(ele.name); 106 107 $Wrapper.append($MovieSection); 108 }); 109 } 110 }) 111 }else { 112 113 } 114 } 115 }); 116 117 </script> 118 </body> 119 </html>
下面利用 $.Deferred() 和 .then() 解决回调地狱, 并没有形成三角区,而是直线,而且一个回调函数只做一件事。 不像上面的 第一个回调函数一样,一个回调函数,做了全部事情
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 * { 10 padding: 0px; 11 margin: 0px; 12 } 13 14 .tpl { 15 display: none; 16 } 17 18 .wrapper { 19 overflow: hidden; 20 border: 2px solid black; 21 width: 600px; 22 margin: 100px auto 0px; 23 } 24 .movieSection { 25 float: left; 26 width: 180px; 27 height: 180px; 28 padding: 10px; 29 } 30 31 .movieSection img { 32 width: 100%; 33 height: 150px; 34 cursor: pointer; 35 } 36 37 .movieSection h3 { 38 height: 30px; 39 } 40 </style> 41 </head> 42 <body> 43 <!-- 基本结构 --> 44 <div class="wrapper"> 45 <div class='tpl'> 46 <img src=""></img> 47 <h3 class='movieName'></h3> 48 </div> 49 </div> 50 51 <script src='./jquery.js'></script> 52 <script> 53 54 (function () { //实际上返回ajax ,是返回ajax 里面的 deferred.promise 对象 55 return $.ajax({//把ajax 返回出去。外面可以.then 可以拿到 done回调函数 56 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', 57 type: 'POST', 58 data: { 59 username: 'fafa', 60 password: '123123' 61 } 62 }); 63 })() 64 .then(function (res) { 65 if (res.data.power == 'root') { 66 return $.ajax({ 67 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList', 68 type: 'GET', 69 }); 70 } 71 }) 72 .then(function (res) { 73 var data = res.data; 74 var $Wrapper = $('.wrapper'); 75 var df = $.Deferred(); 76 $.each(data, function(index, ele) { 77 // ele.name ele.poster 78 var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection'); 79 $MovieSection 80 .data({id: ele.id}) 81 .on('click', function () { 82 df.resolve( $(this) ); 83 }) 84 .children() 85 .eq(0).attr('src', ele.poster) 86 .next().text(ele.name); 87 $Wrapper.append($MovieSection); 88 }); 89 return df.promise(); 90 }) 91 .then(function (dom) { 92 return $.ajax({ 93 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo', 94 type: 'GET', 95 data: { 96 movieId: dom.data('id') 97 } 98 }); 99 }) 100 .then(function (res) { 101 var data = res.data; 102 var direct = data.direct; 103 var gut = data.gut; 104 var mainActor = data.mainActor; 105 var screenWriter = data.screenwriter; 106 107 var htmlStr = '<div class="mask"> 108 <p>导演: ' + direct + '</p> 109 <p>剧情: ' + gut + '</p> 110 <p>主演: ' + mainActor.reduce(function (prev, curv) { 111 prev += curv + ' '; 112 return prev; 113 }, '') + '</p> 114 <p>编剧: ' + screenWriter.reduce(function (prev, curv) { 115 prev += curv + ' '; 116 return prev; 117 }, '') + '</p> 118 </div>' 119 120 $(htmlStr).appendTo('body') 121 }); 122 123 124 125 </script> 126 </body> 127 </html>