Promise API
-
promise 构造函数:
promise(excutor){}- excutor函数:同步执行
(resolver, reject) => {} - resolver函数:函数内部定义成功时调用的函数
value => {} - reject函数:函数内部定义失败时调用的函数
reason => {}
说明:excutor会在promise内部立即同步回调,异步操作代码在执行器中执行
- excutor函数:同步执行
-
Promise.prototype.then()方法:
(onResolved, onRejected) => {}- onResolved函数:成功的回调函数
(value) => {} - onRejected函数:失败的回调函数
(reason) => {}
说明:指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调,返回一个新的promise对象
- onResolved函数:成功的回调函数
-
Promise.prototype.catch()方法:
(onRejected) => {}- onRejected函数:失败的回调函数
(reason) => {}
说明:then()的语法糖,相当于:
then(undefined, onRejected) - onRejected函数:失败的回调函数
-
Promise.resolve()方法:
(value) => {}- value:成功的数据或promise对象
说明:返回一个成功/失败的promise对象
-
Promise.reject()方法:
(reason) => {}- reason:失败的数据或promise对象
说明:返回一个成功/失败的promise对象
-
Promise.all()方法:
(promises) => {}- promises:包含n个promises的数组
说明:返回一个新的promise,只有所有的promise都成功才成功,有一个失败了就直接失败
-
Promise.race()方法:
(promises) => {}- promises:包含n个promises的数组
说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
以下这种情况,在回调中即执行了resolve,又执行了reject,这两个同时存在时,第二个没有效果。为什么呢?因为之前说过的,Promise 的状态只改变一次(pending => resolved / pending => rejected)
-
基本语法
new Promise((resolve, reject) => { setTimeout(() => { resolve('success data'); // reject('failed data'); }, 1000); }).then( value => { console.log('成功的回调函数 onResolved()1:', value); } ).catch( reason => { console.log('失败的毁掉函数 onRejected()1:',reason); } )// 产生一个成功值为1的promise对象 const p1 = new Promise((resolve, rejected) => { resolve(1) }); // 下面p2这个和上面p1效果一样,是上面的语法糖 const p2 = Promise.resolve(2); const p3 = Promise.reject(3); // 得到结果 p1.then(value => {console.log(value)}); p2.then(value => {console.log(value)}); // 失败的时候下面这两种方法一样 p3.then(null, reason => {console.log(reason)}); p3.catch(reason => {console.log(reason)}) -
Promise.all
const p1 = new Promise((resolve, rejected) => { resolve(1) }); const p2 = Promise.resolve(2); const p3 = Promise.reject(3); const pAll = Promise.all([p1, p2, p3]) pAll.then( value => { console.log('all onResolved(): ', value); }, reason => { console.log('all onRejected(): ', reason); } )上面的结果打印出来为3的原因:
promise.all()方法的返回值中只要有一个失败了那么结果就是失败的。只有所有的都成功了才成功修改一下,去掉p3,将成功的value改为values👇:
const p1 = new Promise((resolve, rejected) => { resolve(1) }); const p2 = Promise.resolve(2); const pAll = Promise.all([p1, p2]) pAll.then( values => { console.log('all onResolved(): ', values); }, reason => { console.log('all onRejected(): ', reason); } )可以看到返回的结果是一个成功数据的数组
-
Promise.race() 【rece:竞赛。谁的速度快就输出谁的】
可以看到上面输出的是p1的值,因为我们这里只是输出数字,并没有太多的逻辑,所以基本就是按照数组里面的先后顺序来输出
如果想让失败的p3先输出的话就把p3放到最前面来
但是如果给它加上一些逻辑,比如说按照之前的顺序[p1, p2, p3],给p1加上计时器,然后就会看到结果不同了
这里可以看到虽然也是成功的回调,但是这次是p2的值了
所以说,最后的结果值取决于谁先完成
Promise 的几个关键问题
如何改变promise的状态?
- resolve(value):如果当前是pending就会变为resolved
- rejected(reason):如果当前是pending就会变为rejected
- 抛出异常:如果当前是pending就会变成rejected
const p = new Promise((resolve, reject) => {
throw new Error("err");
})
p.then(
value => {
console.log(value);
},
reason => {
console.log(reason);
}
)
const p = new Promise((resolve, reject) => {
// resolve(1);
// reject(2);
// 抛出异常,promise变为rejeted的失败状态,reason为抛出的error
throw new Error("err");
// 抛出异常,promise变为rejeted的失败状态,reason为抛出的3
// 从语法上来说是可以抛出任何东西,但是真正在项目中抛的话就是error
throw 3;
})
p.then(
value => {
console.log(value);
},
reason => {
console.log(reason);
}
)
一个promise指定多个成功/失败回调函数,都会调用吗?
当promise改变对应状态时都会调用
const p = new Promise((resolve, reject) => {
// resolve(1);
// reject(2);
throw new Error("err");
throw 3;
})
p.then(
value => {console.log(value);},
reason => {console.log(reason);}
)
p.then(
value => {console.log(value);},
reason => {console.log(reason);}
)
改变promise状态和指定回调函数谁先谁后?
- 都有可能。正常情况下是先指定回调再改变状态,但也可以先改变状态再指定回调
- 如何先改状态再指定回调
- 在执行器中直接调用resolve()/reject()
- 延迟更长时间再调用then()
- 什么时候才能得到数据?
- 如果先指定回调,那么当状态发生改变时,回调函数就会调用,得到数据
- 如果先改变状态,那么当指定回调时,回调函数就会调用,得到数据
// 常规:先指定回调,后改变状态
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1); // 后改变状态(同时指定数据),异步执行回调函数
}, 1000);
}).then( // 先指定回调函数,保存当前指定的回调函数
value => { console.log(value); },
reason => { console.log(reason); }
)
// 先改状态,后指定回调函数
new Promise((resolve, reject) => {
resolve(1); // 先改变状态(同时指定数据)
}).then( // 后指定回调函数,异步执行回调函数
value2 => { console.log(value2); },
reason2 => { console.log(reason2); }
)
// 还有一种方法,就是自己可以控制先后(先改状态,后指定回调函数)
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 1000);
})
setTimeout(() => {
p.then(
value3 => { console.log(value3); },
reason3 => { console.log(reason3); }
)
}, 1100);
promise 无论是成功还是失败的回调函数都是异步执行的
promise.then()返回的新的promise的状态由什么来决定?
- 简单表达:由then()指定的回调函数执行的结果决定
- 详细表达:
- 如果抛出异常:新的promise变为rejected,reason变为抛出的异常
- 如果返回的是非promise的任意值,新的promise变为resolve,value为返回的值
- 如果返回的是另一个新的promise,此promise的结果就会变为新的promise的结果
new Promise((resolve, reject) => {
resolve(1);
}).then(
value => {console.log("onResolved1()", value);},
reason => {console.log("onRejected1()", reason);}
).then(
value => {console.log("onResolved2()", value);},
reason => {console.log("onRejected2()", reason);}
)
说明:因为promise中执行的是resolve,所以then中执行的是value,因此第一个打印的是1;又因为第一个then里面没有return出一个值,所以第一个then执行完返回的值为undefined,那么第二个then执行的时候就相当于是undefined.then(),所以第二个then执行出来的值是undefined
new Promise((resolve, reject) => {
resolve(1);
// reject(2);
}).then(
value => {
console.log("onResolved1()", value);
return 2;
// 打印结果:
// onResolved1() 1
// onResolved2() 2
return Promise.resolve(3);
// 打印结果:
// onResolved1() 1
// onResolved2() 3
return Promise.reject(4);
// 打印结果:
// onResolved1() 1
// onRejected2() 2
},
reason => {console.log("onRejected1()", reason);}
).then(
value => {console.log("onResolved2()", value);},
reason => {console.log("onRejected2()", reason);}
)
说明:第一个then成功,第二个then也就成功,成功返回的值和第一个一样。同理,第一个then失败,第二个then也就失败,失败返回的值和第一个一样
new Promise((resolve, reject) => {
// resolve(1);
reject(2);
}).then(
value => {console.log("onResolved1()", value);},
reason => {console.log("onRejected1()", reason);}
).then(
value => {console.log("onResolved2()", value);},
reason => {console.log("onRejected2()", reason);}
)
promise如何串联多个操作任务?
- promise的then()返回一个新的promise,可以看成then()的链式调用
- 通过then的链式调用串联多个同步/异步任务
要想在回调函数中执行异步任务,需要将异步任务封装进promise对象
new Promise((resolve, reject) => {
setTimeout(() => {
console.log("执行任务1(异步)");
resolve(1);
}, 1000);
}).then(
value => {
console.log('任务1的结果:', value);
console.log('执行任务2(同步)');
return 2;
}
).then(
value => {
console.log('任务2的结果:',value);
return new Promise((resolve, reject) => {
// 启动任务3(异步)
setTimeout(() => {
console.log('执行任务3(异步)');
resolve(3);
}, 1000);
})
}
).then(
value => {
console.log('任务3的结果:', value);
}
)
.then()返回的promise,由回调函数执行的结果决定,和是成功的回调或失败的回调没关系。比如之前的那个undefined
promise 异常传透
- 当使用promise的then链式调用时,可以在最后指定失败的回调
- 前面任何操作出了异常,都会传到最后失败的回调中处理
下面的代码中,执行了reject(1)之后,因为需要找失败对应的reason,如果默认只写了value而没有reason的话,就会一步一步往下走,直到catch()中执行返回打印结果onRejected() 1
这样一步一步往下走也就是传透的意思。而不是一下子就直接到catch()了
但是默认不写reason的时候,其实是相当于给每个里面加了reason => {throw reason}这句或者reason => Promise.reject(reason)这句
new Promise((resolve, reject) => {
reject(1);
}).then(
value => {
console.log('onResolved1()', value);
return 2;
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).then(
value => {
console.log('onResolved2()',value);
},
// 默认不写相当于给这块加了下面这句。与上面效果一样
reason => Promise.reject(reason)
).then(
value => {
console.log('onResolved3()', value);
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).catch(reason => {
console.log('onRejected()', reason);
})
这个时候再给catch后面加一个.then()
new Promise((resolve, reject) => {
reject(1);
}).then(
value => {
console.log('onResolved1()', value);
return 2;
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).then(
value => {
console.log('onResolved2()',value);
},
// 默认不写相当于给这块加了下面这句。与上面效果一样
reason => Promise.reject(reason)
).then(
value => {
console.log('onResolved3()', value);
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).catch(reason => {
console.log('onRejected1()', reason);
}).then(
value => {
console.log('onResolved3()', value);
},
reason => {
console.log('onRejected2()', reason);
}
)
这块因为catch中返回的值是undefined(没有return值,但是没有抛出错误),所以最后的这个then里面走的是console.log('onResolved3()', value);
如果不想最后then里面返回的是undefined,那么就需要在catch中做处理👇
.catch(reason => {
console.log('onRejected1()', reason);
throw reason;
// 或
return Promise.reject(reason);
}).then(
value => {
console.log('onResolved3()', value);
},
reason => {
console.log('onRejected2()', reason);
}
)
中断promise链?
- 当使用promise的then链式调用时,在中间中断,不会调用后面的回调函数
- 放大:在回调函数中返回一个pending状态的promise对象
new Promise((resolve, reject) => {
reject(1);
}).then(
value => {
console.log('onResolved1()', value);
return 2;
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).then(
value => {
console.log('onResolved2()', value);
},
// 默认不写相当于给这块加了下面这句。与上面效果一样
reason => Promise.reject(reason)
).then(
value => {
console.log('onResolved3()', value);
},
// 默认不写相当于给这块加了下面这句
// reason => {throw reason}
).catch(reason => {
console.log('onRejected1()', reason);
// throw reason;
// 或
// return Promise.reject(reason);
// 如果想中断不执行后面.then()中的方法
// 返回一个pending状态的promise,中断promise链
return new Promise(() => {})
}).then(
value => {
console.log('onResolved3()', value);
},
reason => {
console.log('onRejected2()', reason);
}
)
218

被折叠的 条评论
为什么被折叠?



