1、promise对象值promiseResult
promise对象中的一个属性:[promiseResult]
保存着对象 成功或失败的结果
这个值由resolve和reject函数来操作
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response)
} else {
reject(xhr.status)
}
}
以上代码就是resolve和reject在操作这个promiseResult的值
2、promis的基本流程
3、promise的使用
1、promise的构造函数:Promise(excutor){}
2、Promise.prototype.then:(onResolved,onRejected){}
3、Promise.prototype.catch:(onRejected)=>{}
只能指定失败的回调函数
4、Promise.resolve方法:(value)=>{}
value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
let promise1=Promise.resolve('成功地执行了promise')
//如果传入的参数为非promise类型的对象,则返回的结果为成功的promise对象
console.log(promise1)//打印 成功地执行了promise
//如果传入的参数为promise对象,则参数的结果决定了resolve的结果
let promise2=Promise.resolve(new Promise((resolve,reject )=>{
resolve('成功')
}))
console.log(promise2)//打印成功
5、Promise.reject方法:(reason)=>{}
reason:失败的原因
说明:返回一个失败的promise对象
<script>
$('#send_ajax').click(function(){
let promise1=Promise.reject('失败地执行了promise')
//如果传入的参数为非promise类型的对象,则返回的结果为成功的promise对象
console.log('promise1',promise1)//打印 失败地执行了promise
//如果传入的参数为promise对象,则参数的结果决定了resolve的结果
let promise2=Promise.reject(new Promise((resolve,reject )=>{
reject('失败')
}))
console.log('promise2',promise2)//打印成功
promise1.catch((reason)=>{
console.log('promise1',reason)
})
promise2.catch((reason)=>{
console.log('promise2',reason)
})
let promise3=Promise.reject(new Promise((resolve,reject )=>{
resolve('成功')
}))
console.log('promise3',promise3)//及时传入成功的promise最后也是失败
promise3.catch((reason)=>{
console.log('promise3',reason)
})
})
</script>
6、Promise.all方法:(promises)=>{}
promises:包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
- 如果都成功,则返回的结果是成功的结果值组成的数组
- 如果有一个失败,则返回的是失败的那个promise的值
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('p1 成功')
})
const p2=new Promise((resolve,reject)=>{
resolve('p2 ok')
})
const p3=new Promise((resolve,reject)=>{
resolve('p3 success')
})
const resualt=Promise.all([p1,p2,p3])
console.log(resualt)
})
</script>
如果有一个失败
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('p1 成功')
})
const p2=new Promise((resolve,reject)=>{
reject('p2 失败')
})
const p3=new Promise((resolve,reject)=>{
resolve('p3 success')
})
const resualt=Promise.all([p1,p2,p3])
console.log(resualt)
p2.catch((err)=>{
console.log('p2==='+err)
})
resualt.catch((err)=>{
console.log('p**resualt==='+err)
})
})
</script>
如果有一个以上的reject则显示第一个reject的结果,可能是,发现第一个reject了就不再往下计算了
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
reject('p1 fail')
})
const p2=new Promise((resolve,reject)=>{
reject('p2 失败')
})
const p3=new Promise((resolve,reject)=>{
resolve('p3 success')
})
const resualt=Promise.all([p1,p2,p3])
console.log(resualt)
p1.catch((err)=>{
console.log('p1==='+err)
})
p2.catch((err)=>{
console.log('p2==='+err)
})
resualt.catch((err)=>{
console.log('p**resualt==='+err)
})
})
</script>
7、Promise.race方法:(promises)=>{}
promises是包含n个promise的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('p1 成功')
})
const p2=new Promise((resolve,reject)=>{
reject('p2 失败')
})
const p3=new Promise((resolve,reject)=>{
resolve('p3 success')
})
const resualt=Promise.race([p1,p2,p3])
console.log(resualt)
})
</script>
4、promise的几个关键问题
1、promise的状态如何改变
promise状态是pending
使用resolve改变为fulfilled也就是成功
使用reject改变为reject
使用throw也可以改变为reject
2、一个promise指定多个成功/失败回调函数,都会调用吗
当promise改变为对应状态时都会调用
3、改变promise状态和指定回调函数谁先谁后
1、都有可能,正常是先指定回调再改变状态,但也有可能先改变状态,再指定回调
2、如何先改状态再指定回调
a,在执行器中直接调用resolve()/reject()//resovle里是同步任务这线改变了状态
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('p1 成功')//先改变状态
})
p1.then(value=>{ //然后再指定回调
console.log(value)
})
})
</script>
b、延迟更长时间才调用then()//一般是使用了settimeout等异步操作或者耗时操作
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功')
},1000)
})
p1.then(value=>{ //然后再指定回调
console.log(value)
})
})
</script>
3、什么时候才能得到数据(回调函数声明时候执行)
a、如果先指定回调,那么当状态发生改变时,回调函数就会调用,得到数据
b、如果先改变状态,那当指定回调是,回到函数就会调用,得到数据。
4、promise.then()返回的新promise的结果状态由声明决定
a、由then()指定的回调函数执行的结果决定
b-1:如果抛出异常,新promise变为rejected,reason为抛出的异常
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
throw '出错了'
})
const result=p1.then(value=>{ //然后再指定回调
console.log(value)
})
console.log(result)
})
</script>
b-2:如果返回的是非promise的任意值,新promise变为resolve,value为返回值
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('成功')
})
const result=p1.then(value=>{ //然后再指定回调
return '返回一个非promise内容'
})
console.log(result)//result的值就是then里面返回的结果
})
</script>
b-3:如果返回的事另一个新promise,此promise的结果就会变成新promise的结果
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
resolve('成功')
})
const result=p1.then(value=>{ //然后再指定回调
return p2=new Promise((resolve,reject)=>{
resolve('ok')
})
})
console.log(result)//result的值就是then里面返回的结果
result.then((value)=>{
console.log('上一个promise返回的值是'+value)
},()=>{})
})
</script>
这位链式调用then()埋下了伏笔
5、promise如何串联多个操作任务
如果promise的then()返回一个新的promise,可以进行then()的链式调用
通过then的链式调用串联起多个同步/异步任务
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p1.then((value)=>{
return new Promise((resolve,reject)=>{
resolve('成功')
})
})
.then((value)=>{
console.log(value)//成功
})
.then((value)=>{
console.log(value)//undefined
})
})
</script>
6、promise的异常穿透
1、当使用promise的then链式调用时,可以在最后指定失败的问题
2、前面任何操作除了异常,都会传到最后失败的回调中
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p1.then((value)=>{
return new Promise((resolve,reject)=>{
reject('失败')
})
})
.then((value)=>{
console.log(value)//成功
})
.then((value)=>{
console.log(value)//undefined
}).catch(err=>{ //也可以使用then
console.log(err)//失败
})
})
</script>
穿透
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p1.then((value)=>{
return new Promise((resolve,reject)=>{
resolve('成功')
})
})
.then((value)=>{
console.log(value)//成功
})
.then(()=>{
throw '失败啦++++'
})
.then((value)=>{
console.log(value)//undefined
})
.catch(err=>{ //也可以使用then
console.log(err)//失败啦++++
})
})
</script>
7、中断promise链
1、当使用promise的then链式调用时,在中间中断,不再调用后面的回调函数
2、办法(唯一方法):在回调函数中返回一个pendding状态的promise对象(pending是初始化状态,如果返回的事pending状态,说明状态没有改变,后续的promise状态改变都不起作用)
<script>
$('#send_ajax').click(function(){
const p1=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok')
},1000)
})
p1.then((value)=>{
return new Promise((resolve,reject)=>{
resolve('成功')
})
})
.then((value)=>{
console.log(value)//成功
})
.then(()=>{
console.log('111111')
return new Promise(()=>{
//啥也不执行,pending初始状态不改变,因此,后续的promi都不执行
})
})
.then((value)=>{
console.log(value)//undefined
})
.catch(err=>{ //也可以使用then
console.log(err)//失败啦++++
})
})
</script>