这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战
hi 我是小十七_,之前总结过一些 Promise 的基础知识,这是第二篇 Promise 总结(二)Promise 解决的问题,建议先看第一篇,分享给大家~
Promise
解决控制反转的问题
比如我们依赖第三方库的支付系统:
analyse.buySomething(price, function(){
// 弹出支付成功框
})
在第三方支付分析工具的回调函数中,写购买的语句,调用回调函数的决定权在第三方工具手中,可能会
- 调用过早/过晚
- 回调未调用
- 回调调用次数过多/过少
- 未按规则传递参数
- 吞掉错误或异常
- 是可信任的 Promise 吗
调用过早/过晚
Promise 原型上的 then 方法,是异步调用的,在下一个时间点一定会被触发。
回调未调用
如果 Promise 本身永远没有被决议,可以使用 竞态 机制,给他一个竞争者。
function timeOutPromise(delay){
return new Promise(function(resolve, reject){
window.setTimeout(function(){
reject('timeout!')
}, delay)
})
}
function handlePromise(){
return new Promise(function(resolve, reject){
})
}
// 两个 Promise 谁先决议,后面 then 为哪个的结果
Promise.race([handlePromise(), timeOutPromise(3000)]).then(function(res){
console.log(res);
}, function(err){
// 可能是代码报错,foo返回拒绝,没按时完成
// 根据 err 判断
console.log(err);
})
调用次数过少或过多
过少相当于上一节说的回调未被调用,也就是0次 过多,因为 Promise 只能被决议一次,如果调用多次 resolve 或 reject,then 也只会被调用一次,即只取第一次的回调结果。
未能传递参数 / 环境值
没有传递值的话默认是 undefined。 如果 resolve 或 reject 中传递了多个参数,会只取第一个,后面的参数被忽略,所以,如果传递多个值,把他们放到数组或对象中。
吞掉错误或异常
p.then 本身返回了一个新的 Promise,来接收里面代码的错误,不会影响 p 这个 Promise 决议的结果。
function promiseError(){
return new Promise(function(resolve, reject){
console.log(b);
resolve(2)
})
}
promiseError().then(function(res){
console.log(res)
}, function(err){
console.log(err) // ReferenceError: b is not defined
console.log(c)
}).then(function(res){
console.log(res)
}, function(err){
console.log(err) // ReferenceError: c is not defined
})