Promise关键问题
修改用户的状态
如果没有经过res(value)或者rej(value),当前状态一般都是pedding
<script>
let p = new Promise((res,rej)=> {
//res('ok') // 成功情况下 把原来的pending => fulfilled(res)
//rej('err') // 失败时 把pending => rejected
//抛出错误
throw '出问题'
})
console.log(p);
</script>
执行多个回调
promise指定多个成功/失败的回调函数,当promise改变为对应状态的时候调用
<script>
let p = new Promise((res, rej) => {
res('ok') //当pending => fulfilled(res),就可以执行以下回调,若不执行res,即pedding没有改变,则无法进去回调
})
//指定回调1
p.then(val => {
console.log(val)
})
//指定回调2
p.then(val => {
alert(val)
})
</script>
改变状态和指定回调的顺序
同步任务下是先改变状态后执行回调;异步任务下是先执行回调后改变状态(下面代码输出ppp)
先改变状态后执行回调方法
1、在执行器中直接调用res()/rej()
2、延长更长事件才调用then
得到数据的方法
不管先改变状态还是后改变状态,一定是通过res/rej来触发then的回调
<script>
// 同步任务下是先改变状态后执行回调;异步任务下是先执行回调后改变状态
let p = new Promise((res, rej) => {
setTimeout(()=> {
res('ok')
},1000)
})
p.then(val => {
console.log('ppp')
})
</script>
then方法返回结果特点
promise.then()返回新promise的结果状态由then()指定的回调函数执行的结果决定
<script>
// 同步任务下是先改变状态后执行回调;异步任务下是先执行回调后改变状态
let p = new Promise((res, rej) => {
// setTimeout(()=> {
res('ok')
// },1000)
})
let result=p.then(val => {
// console.log('ppp')
// 1 抛出问题
// throw '问题'
// 2、返回的结果是非promise对象
// return 555
// 3、返回的结果是promise对象
return new Promise((res, rej) => {
//res('success') //promise的值为success
rej('err') //promise的值为err
})
},reason=> {
console.warn(reason);
})
console.log(result);
</script>
promise串联多个操作任务
promise.then()返回一个新的promise,可以开成then()链式调用
通过then()链式调用串联多个同步/异步任务
<script>
let p = new Promise((res, rej) => {
setTimeout(()=> {
res('ok')
},1000)
})
p.then(val => {
return new Promise((res, rej) => {
//如果没有return默认返回undefined
res('success')
})
},reason=> {
console.warn(reason);
}).then(val => {
console.log(val); //获取的结果是success
}).then(val => {
console.log(val); //获取的结果是undefined
})
// (第一个then)p.then返回结果是Promise,而Promise状态由他所指定的回调函数的返回值决定, 倒数第二个(then)中的promise回调没有声明返回值
</script>
promise异常穿透
在使用promise的then链式调用时,可以在最后指定失败的回调
前面任何操作出了异常,可以在最后指定失败的回调
<script>
let p = new Promise((res, rej) => {
setTimeout(()=> {
rej('不ok')
},1000)
})
p.then(val => {
console.log(111);
}).then(val => {
console.log(222);
}).then(val => {
console.log(333);
}).catch(err=> {
console.warn(err);
})
</script>
中断promise链
在使用promise的链式调用时,在中间中断,不再调用后面的回调函数
办法:在回调函数中返回一个pedding状态的promise对象
<script>
let p = new Promise((res, rej) => {
setTimeout(()=> {
res('不ok')
},1000)
})
p.then(val => {
console.log(111);
//想要中断promise链,有且只有一个办法,就是把状态改回pedding,当状态为pedding的时候就不会再执行then
return new Promise(()=> {
} )
}).then(val => {
console.log(222);
}).then(val => {
console.log(333);
}).catch(err=> {
console.warn(err);
})
</script>