js中的promise和then

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>promise学习</title>
		<!-- 在js中,所有代码都是单线程执行的 -->
		<!-- 异步执行:可以使用回调,在ES6中我们可以使用Promise对象来实现 -->
		<!-- 
		 1.1Promise对象,只需要then一个方法,then方法带有如下三个参数
		     1.成功回调
		     2.失败回调
		     3.前进回调(暂时不讲)
		     一个全新的 promise 对象从每个 then 的调用中返回。
		 1.2 Promise对象代表一个异步操作,其不受外界影响,有三种状态
			.Pending进行中
			.Resolved(已完成,又称Fulfilled)
			.Rejected(已失败)
		 1.3使用Promise的优势
			1.3.1 解决回调地狱问题(Callback Hell)
				例如,有时候我们可能会进行多个异步操作,后一个的请求需要上一次请求的返回结果,所以过去我们都是用callback层层嵌套,
				但是多了的话就会出现回调地狱,代码的可读性和维护性都会变得很差
				firstAsync(function(data){
                        //处理得到的 data 数据
						//....
						secondAsync(function(data2){
							//处理得到的 data2 数据
							//....
							thirdAsync(function(data3){
								  //处理得到的 data3 数据
								  //....
							});
					});
				});
			1.3.2 使用promise的话,代码会变得扁平和可读.前面提到了then返回一个promise,因此我们可以将then的调用不停的串联起来,其中then返回的
			promise装载了由调用返回的值.
				firstAsync()
				.then(function(data){
					//处理得到的 data 数据
					//....
					return secondAsync();
				})
				.then(function(data2){
					//处理得到的 data2 数据
					//....
					return thirdAsync();
				})
				.then(function(data3){
					//处理得到的 data3 数据
					//....
				});
			1.3.3 更好的进行错误捕获
				多层嵌套会造成无法捕获异常,使用promise,通过使用reject方法把promise的状态设置为rejected,这样我们在then中就能捕捉到,然后执行失败情况的回调
					function fetch(callback) {
						return new Promise((resolve, reject) => {
						setTimeout(() => {
								reject('请求失败');
							}, 2000)
						})				
					}
					fetch()
						.then(
							function(data){
								console.log('请求处理');
								console.log(data);
							},
							function(reason, data){
								console.log('触发异常');
								console.log(reason);
							}
						);
				当然我们在catch方法中处理reject回调也是可以的,
				function fetch(callback) {
					return new Promise((resolve, reject) => {
						setTimeout(() => {
							 reject('请求失败');
						}, 2000)
					})
				}
				fetch()
					.then(
						function(data){
							console.log('请求处理');
							console.log(data);
						}
					)
					.catch(function(reason){
						console.log('触发异常');
						console.log(reason);
					});
					
		 -->
	</head>
	<body>
		<script type="text/javascript">
						new Promise(function(resolve, reject) {
							console.log('start new Promise...');
							var timeOut = Math.random() * 2;
							console.log('set timeout to: ' + timeOut + ' seconds.');
							setTimeout(function() {
								if (timeOut < 10) {
									console.log('call resolve()...');
									resolve('200 OK');
								} else {
									console.log('call reject()...');
									reject('timeout in ' + timeOut + ' seconds.');
								}
							}, timeOut * 1000);
						}).then(function(r) {
							console.log('Done: ' + r);
						}).catch(function(reason) {
							console.log('Failed: ' + reason);
						});
// 			promise的使用详解,简单来讲,then方法就是把原来的回调写法分离出来,在异步执行操作执行完成后,用链式调用的方式,回调函数;
// 			我们可以在then方法中继续写promise对象并返回,然后继续调用then进行回调操作

			// then方法举例          例如 学习 考试  放假
			function study() {
				var p = new Promise(function(resolve, reject) {
					setTimeout(() => {
						resolve("学习结束,开始考试")
					}, 2000)
				});
				return p;
			}

			function test(data) {
				var p = new Promise(function(resolve, reject) {
					setTimeout(() => {
						resolve("考试结束,开始假期")
					}, 2000)
				});
				return p;
			}

			function holiday(data) {
				var p = new Promise(function(resolve, reject) {
					setTimeout(() => {
						resolve("假期结束,开始上课")
					}, 2000)
				});
				return p;
			}
			// 使用then链式调用这三个方法
			study()
				.then(function(data) {
					console.log(data)
					return test(data);
				})
				.then(function(data) {
					console.log(data)
					return holiday(data)
				})
				.then(function(data) {
					console.log(data)
				})
			// 运行结果
			// 学习结束,开始考试
			// 试结束,开始假期
			// 假期结束,开始上课



			// 2.reject方法
			function learn() {
				var p = new Promise(function(reslove, reject) {
					setTimeout(() => {
						reject("考试不及格")
					}, 1000)
				});
				return p;
			}
			learn()
				.then(test, function(data) {
					console.log(data + "无法放假,复习吧");
				})
			// 执行结果
			// 考试不及格无法放假,复习吧
			// 另外如果我们只要处理失败的情况,可以使用then(null,.....),或者使用catch方法
			learn()
				.then(null, function(data) {
					console.log(data + "无法放假,复习吧");
				})



			// catch方法和then方法的第二个参数一样,用来指定reject的回调
			learn()
				.then(test)
				.catch(function(data) {
					console.log("没得玩了");
				})
			// 另一个作用是,当执行resolve的回调时,如果抛出了异常(代码出错),那么也不会报错卡死js,而是会进到这个catch中
			study()
				.then(function(data) {
					throw new Error("考题泄漏");
					test(data)
				})
				.catch(function(data) {
					console.log(data + "无法继续考试")
				})





			// all方法,提供了并行异步执行操作的能力,并且在所有异步操作执行完后才会执行回调
			// 例如放假要等到学习和考试之后
			setTimeout(() => {
				Promise.all([study(), test(),holiday()])
					.then(function(data) {
						console.log("开始放假了:后面的是data数据   "+data.length+"第一个:"+data[0]+"第二个:"+data[1]+"第三个:"+data[2])
						// 打印结果:   开始放假了:后面的是data数据   3第一个:学习结束,开始考试第二个:考试结束,开始假期第三个:假期结束,开始上课
					})
			}, 1000)
			// race方法,用法与all一样,只是all是等所有的异步操作完成之后,才会执行then回调.而race回调的话只要有一个异步操作执行完毕,就立刻执行then回调;
			//then方法里面的回调中的参数data是一个数组,我们可以得到异步执行操作的结果
			// PS:其他没有执行完毕的异步操作,仍然会继续执行,而不是停止
			setTimeout(() => {
				Promise.race([study(), test()])
					.then(function(data) {
						console.log("考试不考试,学习不学习,都没关系的")
					})
			}, 20000)
			// race的使用场景很多,例如我们可以给某一个race设置请求超时时间
			//考研开始,5s内交卷认为合格,否则认为不合格
			function passTheExam() {
				var p = new Promise(function(resolve, reject) {
					setTimeout(() => {
						resolve("交卷")
					}, 25000);
				})
				return p;
			}

			function requestTimeOut() {
				var p = new Promise(function(resolve, reject) {
					setTimeout(() => {
						reject("考试失败")
					}, 30000);
				})
				return p;
			}
			Promise.race([passTheExam(),requestTimeOut()])
			.then(function(data){
				console.log(data);
			})
			.catch(function(err){
				console.log(err);
			})
		</script>
	</body>
</html>
复制代码


转载于:https://juejin.im/post/5c3b533e6fb9a049ca37963f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值