理解ES6中的Promise

ECMAScript6新增的引用类型promise,是异步编程的一种解决方案,可以通过new操作符来实例化,相对于传统的解决方案(回调地狱)更加强大。所谓promise,简单说就是一个容器,里面保存着某个未来才会结束的事件的结果,从语法上说,promise是一个对象,从他 可以获取异步操作的消息,promise提供了统一的API,各种异步操作都可以用同样的方法进行处理,
1 自己身上有all reject resolve这几个方法
2 原型上有then catch 等方法
3 一旦建立,就无法取消,也不支持进度通知

1、什么是回调地狱?
由于回调函数是异步的,每一层的回调函数都需要依赖上一层的回调执行完,所以形成了层次嵌套的关系,最终形成了回调地狱

doSomething(function(result) {
 doSecondThing(result, function(newResult) {
  doThirdThing(newResult, function(finalResult) {
   console.log(finalResult)
  }, failureCallback)
 }, failureCallback)
}, failureCallback)

通过promise改写上面的代码

doSomething().then(function(result) {
 return doSecondThing(result)
})
.then(function(newResult) {
 return doThirdThing(newResult)
})
.then(function(finalResult) {
 console.log(finalResult)
})
.catch(failureCallback)

链式操作降低了编码难度,代码的可读性明显增强。

2、promise的理解:
2.1 实例对象中的一个属性 PromiseState:
有三种状态

  • pending(待定)
  • fulfilled(兑现,有时候也称为解决resolved)
  • rejected(拒绝)

2.2 实例对象中的另一个属性 PromiseResult:
保存着对象 成功或失败的结果
resolve
reject

// resolve 解决 函数类型的数据
// reject 拒绝 函数类型的数据
const p1 = new Promise ((resolve, reject) => {
	console.log(1) // 执行器函数会在promise内部立即同步执行
	setTimeout(() => {
		let a = 30
		if (a <= 30) {
			resolve() // 将promise对象的状态设置为 成功
		} else {
			reject() // 将promise对象的状态设置为 失败
		}
	})
})
// 调用then方法
p1.then(() => {
	// 状态成功的回调
	alert('恭喜您中奖')
}, () => {
	// 状态失败的回调
	alert('谢谢惠顾')
})
console.log(2)

2.3 promise的基本流程
1、new Promise() pending状态;
2、执行异步操作,如果成功了执行resolve(),promise对象的状态为resolved,如果失败了执行jeject(),promise对象的状态为rejected;
3、then()方法被执行,第一个参数为成功的回调函数,第二个参数为失败的回调函数,并且返回一个新的promise。

2.4 Promise的函数方法

// 如果传入的参数为非promise类型的对象,则返回的结果为成功的promise对象
let p1 = Promise.resolve(123)
console.log(p1)
// 如果传入的参数为promise类型的对象,则参数的结果决定了resolve的结果
let p2 = Promise.resolve(new Promise((resolve, reject) => {
	reject('Error)
}))
p2.catch(err => {
	console.log(err)
})
console.log(p2)
// 返回的结果永远都是失败的
let p1 = Promise.reject(456)
let p2 = Promise.reject(new Promise((resolve, reject) => {
	resolve('OK)
}))
console.log(p1, p2)
let p1 = new Promise((resolve, reject) => {
	resolve('OK)
})
let p2 = Promise.resolve(123)
let p3 = Promise.reject(456)
// 传入的promises数组的结果都为resolved,则返回的新的promise结果为成功
const res1  = Promise.all([p1,p2])
console.log(res1)
// 传入的promises数组的结果有一个为rejected,则返回的新的promise结果为失败
const res2  = Promise.all([p1,p3])
console.log(res2)
// Promise.race()方法,接受一个promises数组参数,返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
let p1 = new Promise((resolve, reject) => {
	resolve('OK)
})
let p2 = Promise.resolve(123)
let p3 = Promise.reject(456)
const res = Promise.race([p1,p2,p3])
console.log(res)

2.5 改变promise对象状态的方式

const p = new Promise ((resolve, reject) => {
	setTimeout(() => {
		let a = NAN
		if (a <= 30) {
			// 第一种方式,resolve函数
			resolve()
		} else if(a > 30) {
			// 第二种方式,reject函数
			reject()
		} else {
			// 第三种方式,throw
			throw new Error('报错了')
		}
	}10)
})
console.log(p)

2.6 当一个promise指定多个成功/失败回调参数,都会调用

const p = new Promise ((resolve, reject) => {
	let a = NAN
	if (a <= 30) {
		resolve(a)
	} else  {
		reject()
	} 
})
// 指定回调1
p.then(res => {
	console.log(res)
})
// 指定回调2
p.then(res => {
	alert(res )
})

2.7 promise对象then方法返回结果特点
promise.then()返回的新的promise的结果状态由then指定的回调函数执行结果决定。

const p = new Promise ((resolve, reject) => {
	resolve('OK')
})
// 执行then方法
const result = p.then(res => {
	console.log(res)
	// 第一张情况,抛出错误
	throw new Error('报错了') // 返回rejected状态
	// 第二张情况,返回一个非promise类型的对象
	return 123  // 返回resolved状态
	// 第三张情况,返回一个promise类型的对象
	return new Promise ((resolve, reject) => {
		reject()  // 返回结果根据此状态决定
	})
}, error => {
	console.log(error )
})

2.8 promise如何串联多个任务
原理是then方法的返回结果也是一个promise对象

const p = new Promise ((resolve, reject) => {
	setTimeout(() => {
		resolve('OK')
	}10)
})
p.then(res => {
	return new Promise ((resolve, reject) => {
		resolve('success')
	})
}).then(res => {
	console.log(res) // 'success'
})then(res => {
	console.log(res) // undefined
})

2.9 promise异常穿透
当使用promise的then链式调用,可以在最后指定失败的回调,前面任何操作发生异常,都会传达到最后失败的回调中处理。

const p = new Promise ((resolve, reject) => {
	setTimeout(() => {
		resolve('OK')
	}10)
})
p.then(res => {
	console.log(123)
	throw '报错了'
}).then(res => {
	console.log(456) 
}).then(res => {
	console.log(789) 
}).catch(err => {
	console.log(err) // '报错了'
})

2.10 如何中断promise链
只有返回一个pending状态的promise对象,才能中断

const p = new Promise ((resolve, reject) => {
	setTimeout(() => {
		resolve('OK')
	}10)
})
p.then(res => {
	console.log(123)
	return new Promise(() => {}) // 中断promise链 不执行后面的方法
}).then(res => {
	console.log(456) 
}).catch(err => {
	console.log(err)
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值