Promise对象异步编程的一种解决方案学习总结

什么是Promise

Promise对象用于表示一个异步操作的最终状态(完成或失败)以及其返回的值

  1. 同步任务会阻塞程序执行(alert、for、…)
  2. 异步任务不会阻塞程序执行(setTimeout、fs.readFiles)
    特点:
  3. 对象的状态不受外界影响‘
  4. 一旦状态改变就不会再变,任何时候都是这种结果.
回调函数与Promise
  1. 回调函数实现元素平移
function moveTo(el, x, y, cb) {
			el.style.transform = `translate(${x}px,${y}px)`;
			setTimeout(function() {
				cb && cb();
			}, 1000)
		}

		let el = document.querySelector('div');
		let bu = document.querySelector('button');
		bu.addEventListener('click', function() {
			moveTo(el, 100, 200, function() {
				moveTo(el, 200, 100, function() {
					moveTo(el, 20, 40, function() {
						moveTo(el, 0, 0, function() {
							console.log('移动结束');
						})
					})
				})
			})
		})
  1. Promise实现
function moveTo(el, x, y) {
			return new Promise(resovle => {
				el.style.transform = `translate(${x}px,${y}px)`;
				setTimeout(function() {
					resovle();
				}, 1000)
			})
		}
		let el = document.querySelector('div');
		let bu = document.querySelector('button');
		bu.addEventListener('click', function() {
			moveTo(el, 100, 200).then(function() {
				console.log("第一次移动");
			 return moveTo(el,20,30)
			 .then(function(){
				console.log("第二次移动")
			 });
			})
		})
信任处理
  • 普通的回调函数可能出现回调地狱问题,你无法预知它要执行几次,
  • 但是Promise对象中的状态一旦被确定为成功或者失败,就不能被修改 执行一次
  • Promise解决了1.第三方库的信任问题 2.回调地狱问题。
错误处理

注意点:Promise中的 then是异步处理

  1. then接受resolve 和 reject两参数来处理错误
function fn(val){
return new Promise((resolve,reject)=>{
if(val){
    resolve({name:'dxy',age:18},{name:'hhh'}); //注意只能拿到一个对象
}else{
       reject('404');
	 }
   })
}

fn(true)
.then((res)=>{
		console.log(res); 
},(error)=>{
	 console.log(error);
  })
		
  1. 实例的catch方法来捕获错误
        fn(true)
		.then((res)=>{
			console.log(res);
			return fn(false)
		})
		.then(()=>{
			console.log("我不会被输出");	
		})
		.catch(error=>{
			console.log(error);
		})
	    //注意:无法捕获最后一个catch中有无错误
		
  1. 无论成功还是是被,finally方法中的内容都会执行
        fn(true)
		.then(res=>{
			console.log(res);
			return fn(false);
		})
		.catch(error=>{
			console.log(error);
			return fn(false) //未对其做处理,所以会报错
		})
		.finally(()=>{
			console.log(100); //无论成功或者失败,都会执行
		})
  1. done( )方法,保证抛出任何可能出现的错误
    因为Promise的内部错误不能冒泡到全局,为此提供了一种done方法,它总是处于回调链的尾端,保证抛出任何可能出现的错误
Promise.prototype.done=function(onFulfilled,onRejected){
this.then(onFulfilled,onRejected)
    .catch(function(){
    //抛出一个全局错误
    setTimeout(()=>{throw reason},0);
})
}
Promise.all()

Promise.all方法用于将多个Promise实例包装成一个新的Promise 实例

let p=Promise.all([promise1,promise2])  //:Promise

注意点:

  • 返回的每个成员都是Promise实例数组
  • p的状态由promise1,promise2决定,只有两者的状态都变为fulfilled,p的状态才会变为fulfilled,此时promise1,promise2的返回值组成一个数组,传递给p的回调函数
  • 只要promise1,promise2中一个被Rejected,p的状态就会变成Rejecte,此时第一个被Rejected的实例的返回值会传递给p的回调函数。
function getData1(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
					console.log("我是第一条数据")
				resolve('data1')	
				},1000)
			})
		}
		function getData2(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
					console.log("我是第二条数据")
				resolve('data2')	
				},1000)
			})
		}
		function getData3(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
					console.log("我是第三条数据")
				resolve('data3')	
				},1000)
			})
		}
		function getData4(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
					console.log("我是第四条数据")
				resolve('data4')	
				},2000)
			})
		}
		
		let p=Promise.all([getData1(),getData2(),getData3(),getData4()]);
		p.then(arr=>{
			console.log(arr);
		})
  • 注意点:若promise.all传参数组为空,则直接返回成功
Promise.race()

注意点:

  • 只要p1,p2,p3中实例率先改变状态,p的状态跟着改变,
    率先改变状态的Promise实例返回值就传递给p的回调函数
  • promise.race传参为空数组,就会挂起什么也不输出。
let p=Promise.all(p1,p2,p3]);
function getData1(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
				console.log("我是第一条数据")
				resolve('data1')	
				},1000)
			})
		}
		function getData2(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
				//console.log("我是第二条数据")
				reject('data2 ere')	
				},500)
			})
		}
		function getData3(){
			return new Promise((resolve,reject)=>{
				setTimeout(function(){
				console.log("我是第三条数据")
				resolve('data3 ')	
				},1000)
			})
		}
		let p=Promise.race([getData1(),getData2(),getData3()]);
		p.then(arr=>{
			console.log(arr);
		},error=>{
			console.log(error);
		})
Promise.resolve &Promise.reject
Promise.resolve

有时需要将现有的对象转为Promise对象,Promise.resolve方法就起到这个作用
其参数传递分为以下四种情况:

  1. 参数是一个Promise实例
let p=new Promise(resolve=>{
resolve("hi");
})
let p2=Promise.resolve(p);
p2.then(data=>{
console.log(data);
})
  1. 参数是一个thenable对象
let thenable={
then:function(resolve,reject)=>{
resolve(23);
  }
}
let p1=Promise.resolve(thenable);
p1.then(data=>{
console.log(data);//23
})
  1. 参数根本不是对象
    如果参数是个原始值,那么Promise.resolve方法返回一个新的Promise对象,状态为Resolved
let p=Promise.resolve("dxy");
p.then(res=>{
console.log(res);//dxy
})
  1. 不带任何参数
    直接返回一个Resolved状态的Promise对象
    注意点:promise为微任务在本轮时间循环结束时执行,而不是在下一轮时间循环开始时
Promise.reject()

Promise.reject(reason)方法会返回一个新的Promise实例,状态为Rejected。

let p=Promise.reject('error');
//等同于
let p=new Promise((resolve.reject)=>reject('error'));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值