能够看到,这是个构造函数,本身有all,race,reject,resolve方法,原型上有 then,catch方法javascript
let p = new Promise((resolve,reject)=>{
console.log('123')
setTimeout(()=>{
console.log('执行结束')
resolve(321)
},2000)
})
复制代码
结果:
java
上面先执行了随便什么操做,两秒后执行了resolve,打印了执行结束es6
已经知道这是在构造函数Promise上的方法,es6标准上讲resolve是将异步操做状态从pending转为fulfilled,而reject是将状态从pending转为rejectedajax
看不懂?那继续show you the code数组
p.then((data)=>{
console.log(data)
})
复制代码
看结果返回了一个promise对象,咱们知道promise原型上有then方法,所以能够链式操做,很爽!!!promise
打印了321,说明resolve传出的数据咱们能够在then中操做,所以即可以在then中为异步操做的成功或失败状态后设置回调函数,让代码看起来更像同步操做.(解决了回调地狱这个事儿)异步
关于什么是回调地狱,参考:async
简单理解就是函数做为参数层层被调用,会是代码耦合度极高,不利于维护post
tip:es7中的async/await =====>这被称为解决异步问题的终极方法
小明跟爸爸说小明要吃烤肉,爸爸说让小明去买材料,买完材料回来爸爸制做,制做完小明就赶忙吃了溜(就不刷碗!!!!)
let async1 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('买材料')
resolve('买完材料了')
}, 2000)
})
return p
}
let async2 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('制做')
resolve('制做完成,赶忙吃')
}, 2000)
})
return p
}
let async3 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('吃完赶忙溜')
resolve('就不刷碗')
}, 2000)
})
return p
}
复制代码
show you the code
async1().then((data) => {
console.log(data)
return async2()
}).then((data) => {
console.log(data)
return async3()
}).then((data) => {
console.log(data)
})
复制代码
运行结果
一步一步,上一步函数的调用结果做为下一步的参数,将异步操做以同步操做的流程表达出来,避免层层嵌套,完美.
通过上面的例子,应该大概了解了promise是啥,可是里面好像还有个reject咱们还没看,来,继续上面的例子
众所周知,小明是一个调皮的可是注意力不集中的好孩子,在路上,他发现了好甜的水果糖,因而买了水果糖,结果回到家到了第二调用,便带了个error
// 改一下async1()
let async1 = () => {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('买材料')
console.log('看到糖果')
console.log('买了糖果')
if(/*买对了*/ 0){
resolve('买了材料')
}else{
reject('买了糖果')
}
}, 2000)
})
return p
}
// 描述故事
async1().then((data) => {
console.log(data)
return async2()
},(err)=>{
console.log('买错了,快滚')
return
})
//为了描述上面的例子,这里只作了第一步调用
复制代码
结果:
由结果看,then(parm1,parm2)的两个参数,第一个为处理resolve的情况,给resolve添加函数处理,而第二个参数为处理reject的情况,两个参数都为处理函数.
第一个处理函数的参数为resolve传过来的数据,第二个的参数为reject传过来的数据.
单词的一次就是捕获,因此做用是捕获异常,参数为异常处理函数,也就是跟then的第二个参数同样,所以再也不赘述,可是catch有本身的独特的做用(否则凭啥存在)
话很少说,show you the code
const fun = () => {
let p = new Promise((resolve, reject) => {
resolve(123)
})
return p
}
fun().then((data)=>{
console.log(data)
console.log(names)
})
复制代码
上面的例子运行会报names is not defined 的错误,并且不会继续运行了,若是后面有代码会直接中断,而若是加了catch
fun().then((data)=>{
console.log(data)
console.log(names)
}).catch((res)=>{
console.log('出错咯')
}).then((data)=>{
console.log('123')
})
复制代码
看结果
由此,代码出错,会被catch捕获,并作处理,而后能够继续运行代码.
仍是用小明的例子
咱们先把延时时间改一下,好比async1改成4s,async2改成3s,async3改成2s
Promise.all([async1(),async2(),async3()])
// all里传的参数为promise实例的数组
复制代码
看结果
Promise.all()方法的参数为一个数组,数组里各元素均为promise实例,若是不是,会先转换为promise实例.
注意
简单理解就是以跑的慢的为准,跑的慢的跑完了才一块儿处理返回结果.
使用场景
相对all方法,这个就是跑的快的为准,有跑完了的就直接执行then里处理函数
因而上面的代码改用race方法后
Promise.race([async1(),async2(),async3()]).then((datas)=>console.log(datas))
复制代码
结果
async3执行的最快,跑完后便直接处理打印了resolve返回的数据==>'就不刷碗'
使用场景
至此,最经常使用的promise的方法都已经介绍完毕.