ES6的promise解决回调地狱
使用ES5的时候,在多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发
基本理解:
- 是一种承诺,当它成功时执行一些代码,当它失败时执行一些代码
- Promise是一个对象,有then()方法的对象
- promise链
基本用法:
promise执行多步操作非常好用,以吃饭为例,要想在家吃顿饭,是要经过三个步骤的。
- 洗菜做饭。
- 坐下来吃饭。
- 收拾桌子洗碗。
这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。这样一个简单的过程在ES5写起来就要有多层的嵌套。现在用promise来实现。
let state=1;
function step1(resolve,reject){
console.log('1.开始-洗菜做饭');
if(state==1){
resolve('洗菜做饭--完成');
}else{
reject('洗菜做饭--出错');
}
}
function step2(resolve,reject){
console.log('2.开始-坐下来吃饭');
if(state==1){
resolve('坐下来吃饭--完成');
}else{
reject('坐下来吃饭--出错');
}
}
function step3(resolve,reject){
console.log('3.开始-收拾桌子洗完');
if(state==1){
resolve('收拾桌子洗完--完成');
}else{
reject('收拾桌子洗完--出错');
}
}
new Promise(step1).then(function(val){ // .then() 函数接受一个参数,此入参必须返回一个Promise对象。可传递一个返回Promise的函数
console.log(val); // 洗菜做饭--完成
return new Promise(step2);
}).then(function(val){
console.log(val); // 坐下来吃饭--完成
return new Promise(step3);
}).then(function(val){
console.log(val); // 收拾桌子洗完--完成
return val;
});
如何破坏promise链:
function p1() {
return new Promise(function(resolve, reject) {
console.log('p1 resolved')
resolve(123)
})
}
function p2() {
return new Promise(function(resolve, reject) {
console.log('p2 rejected')
reject(456)
})
}
function p3() {
return new Promise(function(resolve, reject) {
console.log('p3 resolved')
resolve(789)
})
}
p1().then(p2).then(p3)
.then(function(data) {
console.log('data: ' + data)
})
.catch(function(error) {
console.log('error: ' + error)
})
console.log会是这样:
p1 resolved
p2 rejected
error: 456
没有看到 p3 的log,而是看到了error message,也就是说:
在一个promise链中,只要任何一个promise被reject,promise链就被破坏了,reject之后的promise都不会再执行,而是直接调用.catch方法。
这也是为什么在standard practice中,一定要在最后加上 .catch 的原因。通过 .catch 能够清楚的判断出promise链在哪个环节出了问题。
如何按顺序执行已经定义的promise:
这个情况在什么时候会用到呢?
有一个任务队列,必须做完A之后才能再去做B,并且AB是相互独立的
假如我现在有一堆promise对象,大概长这样:
//p2, p3与p1相似
//当doSomething()执行完毕的时候,调用resolve()
//使得当前promise状态转变为fulfilled即可
var p1 = new Promise(function(resolve, reject) {
//do something here
//when do something done
resolve();
});
p1.then(function() {
return p2
})
.then(function() {
return p3
})
.catch()
请注意,前一部破坏Promise链中分定义的p1 p2 p3是 函数 ,而此部分定义的p1 p2 p3是 对象!对象!对象!
- promise是一个有then方法的对象,因此p1可以直接调用then
Q:为什么开头调用不是 p1().then ?
A: 因为p1是一个对象啊!!!对象啊!!!象啊!!!啊!!!
- 然而promise链中then方法的入参是 一个返回promise对象的函数 ,p2并不是一个函数,因此不能then(p2);
- 但p2是一个promise对象,已经满足了then方法入参的一半需求,那么写一个函数并且返回p2,就满足了入参的全部需求