提示:解决方案可以直接跳到最后,看目录快速查看要点哦
方法返回值是一个Promise对象?
Promise {<fulfilled>: false}
问题简介:有时候咱们可能会用到异步函数
的返回值的调用
,有可能是一个数组,是一个布尔值等等,但是可能会出现返回值是一个Promise {<fulfilled>: false}
这样的结构,如下图所示,
这一看打印顺序没问题,其实到处都是问题
一、源码及分析问题
注意:onStart中逻辑其实比较复杂,这里为了方便讲解我做了简化
方法源码
简单梳理:一个普通方法使用了一个来自于异步函数 getFraInfo 的返回值 reBack
//根据条件跳转
onStart() {
const fraSate = this.getFraInfo()
if (fraSate) {
uni.redirectTo({url: 'xxx/xxx'})
} else{
uni.redirectTo({url: 'xxx/xxx'})
}
},
//获取跳转条件
async getFraInfo() {
let reBack = false;
await getFraAnyApi({
zhentiId: this.info.zhentiId,
}).then(res => {
if (res.code === 200 && res.data == true) {
reBack = true;
}
});
console.log('reBack',reBack);
return reBack;
},
问题分析
其实眼尖的乖乖已经发现问题了,首先先忽略代码的错误性,通过刚才的截图,我们的reback值是一个布尔值,但是在调用的方法中打印却是一个对象,而且可以看到咱们用到了异步处理,所以问题就在这上面
敲小黑板喽~
讲简单点就是:
- 首先,
async/await
本身就是用来解决.then()
和.catch()
回调地狱的语法糖,结果这里还嵌套混用了,直接导致了then()中的处理时机不对或逻辑不清 - 其次,reBack 的赋值依赖于
getFraAnyApi
的结果,但由于await
和.then
的混用,直接导致reBack
的赋值逻辑不清晰 - 最后,就相当于返回值最终只给到了 async的promise对象,而这个对象
隐式返回
最终把值给了调用它的onStart,大家可以打印看看,就算是没有 return,fraSate的打印结果也会是一个Promise 对象,只是没用里面的值,可以自行验证 (这里作为拓展,可能有语误,自行选择观看)
二、解决方案
1.彻底去异步化(治标不治本)
也就是说,咱们不使用异步调用,就让代码顺序执行,就在.then()中进行操作,缺点就是如果出现接口调用异常可能无法对异常结果进行处理
getFraInfo() {
let reBack = false;
getFraAnyApi({
zhentiId: this.info.zhentiId,
}).then(res => {
if (res.code === 200 && res.data == true) {
reBack = true;
}
});
console.log('reBack',reBack);
return reBack;
},
2.彻底异步化(即治标又治本)
避免混用.then()处理,完全使用 async/await
语法,因为reBack
的赋值依赖于getFraAnyApi
的结果,所以在调用它的值前,咱们需要先拿到他的值
先看结果:
完全按照咱们预想的结果有木有~
靓仔请看代码
//根据条件跳转
async onStart() {
// 使用 try/catch 捕获可能的错误(例如网络错误或 getFraAnyApi 返回的异常,并处理)。
try {
const fraSate = await this.getFraInfo(); // 使用 await 获取布尔值
console.log('fraSate-0',fraSate);
if (fraSate) {
//这里整你想做的事儿
console.log('fraSate-1',fraSate);
}
} catch (error) {
//这里整如果返回结果异常,你想做的事儿
console.error('Error in onStart:', error);
}
},
//获取跳转条件
async getFraInfo() {
let reBack = false; // 默认值为 false
try {
// 使用 await 等待 getFraAnyApi 的结果
const res = await getFraAnyApi({
zhentiId: this.info.zhentiId,
});
// 根据 res 的结果设置 reBack
if (res.code === 200 && res.data === true) {
reBack = true;
}
} catch (error) {
// 捕获可能的错误(例如网络错误)
console.error('Error in getFraInfo:', error);
}
console.log('reBack', reBack);
return reBack; // 返回布尔值 reBack
}
该处使用的url网络请求的数据。
总结
- 问题根源:async 函数会隐式返回 Promise 对象,即使你返回的是布尔值。
- 解决方案:完全使用 async/await 语法,避免混用 .then,并确保调用方使用 await 获取实际值。
如果有问题可以私信我或者留言 and 我会经常分享实际开发中遇到的问题和技术笔记,如果喜欢我的很感谢你能一键三连哦~
瑞思拜~