手把手写:优化回调地狱
解决回调地狱的方法:
1.拆解function
2.事件发布/监听模式
3.Promise
4.generator
5.async/await
实例如下:
1.用户点击多次,可以使用立即函数返回每次点击的值。执行顺序:点击-判断-请求数据-渲染页面
(function () { return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', type: 'POST', data: { userName: 'xjt', //后端写好的接口文件属性 password: '2958' }, }) //如果获取到了,接下来判断是否有权限 })().then(function (res) { //刚写出了个bug,then报未定义,往上找发现没有返回值,需要返回出去 if (res.data.power == 'root') { console.log(res); return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList', type: 'GET' }); } }).then(function (res) { //如果有权限就执行下面的语句 向后端获取数据 获取之后执行点击事件 var data = res.data; var $Wrapper = $('.wrapper'); $.each(data, function (index, ele) { var $MovieSection = $('.tpl').clone().removeClass('tpl') .addClass('movieSection'); $MovieSection .data({ id: ele.id }) .children() .eq(0).attr('src', ele.poster) .next().text(ele.name) .data() // 添加成功后,还需要传给它的父级 $Wrapper.append($MovieSection); }) })
执行点击事件
(function () { return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', type: 'POST', data: { userName: 'xjt', //后端写好的接口文件属性 password: '2958' }, }) //如果获取到了,接下来判断是否有权限 })().then(function (res) { //刚写出了个bug,then报未定义,往上找发现没有返回值,需要返回出去 if (res.data.power == 'root') { console.log(res); return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList', type: 'GET' }); } }).then(function (res) { //如果有权限就执行下面的语句 var data = res.data; var $Wrapper = $('.wrapper'); var df = $.Deferred(); //注册延迟函数 $.each(data, function (index, ele) { var $MovieSection = $('.tpl').clone().removeClass('tpl') .addClass('movieSection'); $MovieSection .data({ id: ele.id }) .on('click', function () { //点击之后传不出去了,可以使用六大原则之一的单一原则 df.resolve(); //点击之后,返回成功的状态 }) .children() .eq(0).attr('src', ele.poster) .next().text(ele.name) .data() // 添加成功后,还需要传给它的父级 $Wrapper.append($MovieSection); }) return df.promise(); //返回注册成功后的函数 现在可以往后执行了 }).then(function () { //处理请求成功的事件 return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo', type: 'GET', //请求方式错了,会请求不到 data: { movieId: $(this).data('id') } }) }).then(function () { //在这获取不到传来的this 怎么办 为什么获取不到 })
如下改 注意:this是jq包裹的对象
完整代码如下:
(function () { return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/power', type: 'POST', data: { userName: 'xjt', //后端写好的接口文件属性 password: '2958' }, }) //如果获取到了,接下来判断是否有权限 })().then(function (res) { //刚写出了个bug,then报未定义,往上找发现没有返回值,需要返回出去 if (res.data.power == 'root') { console.log(res); return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieList', type: 'GET' }); } }).then(function (res) { //如果有权限就执行下面的语句 var data = res.data; var $Wrapper = $('.wrapper'); var df = $.Deferred(); //注册延迟函数 $.each(data, function (index, ele) { var $MovieSection = $('.tpl').clone().removeClass('tpl') .addClass('movieSection'); $MovieSection.data({ id: ele.id }) .on('click', function () { //点击之后传不出去了,可以使用六大原则之一的单一原则 df.resolve($(this)); //点击之后,返回成功的状态 }) .children() .eq(0).attr('src', ele.poster) .next().text(ele.name) .data() // 添加成功后,还需要传给它的父级 $Wrapper.append($MovieSection); }) return df.promise(); //返回注册成功后的函数 现在可以往后执行了 }).then(function (dom) { //处理请求成功的事件 return $.ajax({ url: 'https://easy-mock.com/mock/5c09f40d3c098813c612cce6/movie/movieInfo', type: 'GET', //请求方式错了,会请求不到 data: { movieId: dom.data('id') } }) }).then(function (res) { var data = res.data; //获取数据 // 再把每个数据单独赋值 var direct = data.direct; var gut = data.gut; var mainActor = data.mainActor; //这是一个数组,需要拼成字符串 使用map返回的是一个数组,foreach可以,但返回啥也不是,所以使用reduce遍历,最后返回字符串 var poster = data.poster; var screenWriter = data.screenwriter; var htmlStr = '<div>\ <p>导演:' + direct + '</p>\ <p>剧情:' + gut + '</p>\ <p>主演:' + mainActor.reduce(function (prev, curv) { console.log(mainActor) prev += curv + ' '; //加空字符串是为了把名字分开 return prev; }, '') + '</p>\ <p>编剧' + screenWriter.reduce(function (prev, curv) { prev += curv + ' '; return prev; }) + '</p>\ </div>' // 创建标签没有样式,可以给它加样式 $(htmlStr).appendTo('body').css({ position: 'absolute', left: $(window).outerWidth() / 2, bottom: -100, width: 400, marginLeft: -200 }) })