手把手写:优化回调地狱

解决回调地狱的方法:

  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
		})
	})




posted @ 2019-05-01 17:08  岁月无垠  阅读(257)  评论(0编辑  收藏  举报