在上一篇文我们说到了回调地狱不好的地方,今天我们看看怎么来优化它,让它可以运用到实际开发中。
什么是回调地狱?回调地狱就是一个函数里面嵌套了所有功能函数,然后缩略图形成一个三角形。
这样的代码可复用性不强。阅读性差也代表可维护性差。扩展性也差。
也不符合设计模式的六大原则, 其中的 单一职责原则, 和 开闭原则
单一职责原则:尽量让一个函数只做一件事情
开闭原则:函数应该对扩展开放,对修改关闭
---------------------------------------------------------------------
我们先来看一下未优化前的代码,未优化前的代码同样可以实现该功能。
但只适合小公司开发,因为没有人去看你的代码,大公司还是需要优化的
代码如下:
1 <!DOCTYPE html>
2 <html lang="en">
3
4 <head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="X-UA-Compatible" content="ie=edge">
8 <title>Document</title>
9 <style>
10 * {
11 padding: 0px;
12 margin: 0px;
13 }
14
15 .tpl {
16 display: none;
17 }
18
19 .wrapper {
20 overflow: hidden;
21 border: 2px solid black;
22 width: 600px;
23 margin: 100px auto 0px;
24 }
25
26 .movieSection {
27 float: left;
28 width: 180px;
29 height: 180px;
30 padding: 10px;
31 }
32
33 .movieSection img {
34 width: 100%;
35 height: 150px;
36 cursor: pointer;
37 }
38
39 .movieSection h3 {
40 height: 30px;
41 }
42 </style>
43 </head>
44
45 <body>
46 <div class="wrapper">
47 <div class="tpl">
48 <img></img>
49 <h3 class="movieName"></h3>
50 </div>
51 </div>
52 <script src="../jq/jquery-3.3.1/jquery-3.3.1.js"></script>
53 <script>
54
55 //模拟电影网站,判断用户是否为该网址的vip用户(最高权限为vip)
56 //如果vpi就展示出vip电影,点击相应的电影显示出该电影的详细介绍
57
58
59 //发送网络请求
60 $.ajax({
61 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', //向此服务器请求
62 type: 'POST', //获取数据类型
63 data: { //假设传入了账号密码,已经验证成功了。为了演示我们就不写input框来输入了
64 username: 'ypx',
65 password: '123'
66 },
67 success: function (res) { //请求成功后执行的函数
68 if (res.data.power == 'root') { //判断该用户是否为最高vip,如果是就返回出vip电影资源
69 //vip 网络地址发送请求
70 $.ajax({
71 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList',
72 //正常开发中,数据不应该在这拿,
73 //应该在请求返回来的res中获取数据的,我们现在为了演示就在这里获取第二次数据了
74
75 type: 'GET',
76 success: function (res) {
77 var data = res.data; //声明一个变量为获取到的数据
78 var $Wrapper = $('.wrapper'); //获取wrapper准备存放数据
79 $.each(data, function (index, ele) { //循环所有数据里面的东西
80 //ele.name 数据里面的电影名称 ele.poster 数据里面的海报地址
81
82 var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection');
83 //把HTML结构的模板给克隆过来存放数据,再把模板的类名换成要放数据结构的类名
84
85 $MovieSection.data({ id: ele.id }).on('click', function () {//给获取数据加上id,添加点击事件
86 $.ajax({
87 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo',
88 type: 'GET',
89 data: {
90 movieId: $(this).data('id') //点击谁this就指向谁
91 },
92 success: function (res) {
93 var data = res.data;
94 var direct = data.direct;
95 var gut = data.gut;
96 var mainActor = data.mainActor;
97 var screenWriter = data.screenwriter;
98 var htmlStr = '<div class="mask">\
99 <p>导演: ' + direct + '</p>\
100 <p>剧情: ' + gut + '</p>\
101 <p>主演: ' + mainActor.reduce(function (prev, curv) {
102 prev += curv + ' ';
103 return prev;
104 }, '') + '</p>\
105 <p>编剧: ' + screenWriter.reduce(function (prev, curv) {
106 prev += curv + ' ';
107 return prev;
108 }, '') + '</p>\
109 </div>'
110 $(htmlStr) //把数据结构加到body里面
111 .appendTo('body');
112 }
113 });
114 })
115 .children() //获取克隆后的模板结构下面的所有子元素
116 .eq(0) //选中元素中的第一个
117 .attr('src', ele.poster) //给属性加上数据中的海报
118 .next() //给下一个兄弟元素
119 .text(ele.name); //给文本加上数据中的电影名称
120 $Wrapper.append($MovieSection);//把MouseEvent填充到wrapper标签下面
121 });
122 }
123 })
124 } else {
125 //不是vip
126 }
127 }
128 });
129 </script>
130 </body>
131
132 </html>
接下来我们具体来看是怎么优化的,最后会附上完整代码
第一步
判断该用户是否为VIP用户
第二步
确定为VIP用户,返回VIP资源
第三步
将资源的电影海报,电影名称可视化
第四步
添加点击事件,点击海报后显示出详情介绍
衔接上下图片↑↓
最后我们再来看一下成品图:
最后附上完整代码加注释:
1 (function () {
2 return $.ajax({
3 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power',
4 type: 'POST',
5 data: { //获取账号密码
6 username: 'ypx',
7 password: '123'
8 },
9 });
10 })().then(function (res) {
11 if (res.data.power == 'root') { //判断该账号密码是否为最高权限(VIP用户),是的话就发送网络请求获取VIP用户的数据
12 return $.ajax({
13 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList',
14 //正常开发中,数据不应该在这拿,
15 //应该在请求返回来的res中获取数据的,我们现在为了演示就在这里获取第二次数据了
16
17 type: 'GET'
18 });
19 }
20 }).then(function (res) {
21 var data = res.data; //声明一个变量为获取到的数据
22 var $Wrapper = $('.wrapper'); //获取wrapper准备存放数据
23 var df = $.Deferred();
24 $.each(data, function (index, ele) { //循环所有数据里面的东西
25 //ele.name 数据里面的电影名称 ele.poster 数据里面的海报地址
26
27 var $MovieSection = $('.tpl').clone().removeClass('tpl').addClass('movieSection');
28 //把HTML结构的模板给克隆过来存放数据,再把模板的类名换成要放数据结构的类名
29
30 $MovieSection.data({ id: ele.id })
31 .on('click', function () { //在这里添加点击事件,由于在里面返回数据外面会接收不到,所以我们在里面弄一个注册成功可以返回
32 df.resolve(); //注册成功
33 })
34 .children() //获取克隆后的模板结构下面的所有子元素
35 .eq(0) //选中元素中的第一个
36 .attr('src', ele.poster) //给属性加上数据中的海报
37 .next() //给下一个兄弟元素
38 .text(ele.name); //给文本加上数据中的电影名称
39 $Wrapper.append($MovieSection); //把MouseEvent填充到wrapper标签下面
40 });
41 return df.promise(); //只返回注册方法,不返回出执行方法
42 }).then(function (res) {
43 return $.ajax({
44 url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo',
45 type: 'GET',
46 data: {
47 movieId: $(this).data('id') //点击谁this就指向谁
48 }
49 });
50 }).then(function(res){
51 var data = res.data;
52 var direct = data.direct;
53 var gut = data.gut;
54 var mainActor = data.mainActor;
55 var screenWriter = data.screenwriter;
56 var htmlStr = '<div class="mask">\
57 <p>导演: ' + direct + '</p>\
58 <p>剧情: ' + gut + '</p>\
59 <p>主演: ' + mainActor.reduce(function (prev, curv) {
60 prev += curv + ' ';
61 return prev;
62 }, '') + '</p>\
63 <p>编剧: ' + screenWriter.reduce(function (prev, curv) {
64 prev += curv + ' ';
65 return prev;
66 }, '') + '</p>\
67 </div>'
68 $(htmlStr) //把数据结构加到body里面
69 .appendTo('body');
70 });
谢谢观看!!! 谢谢观看!!! 谢谢观看!!!