为什么调用async函数getUserData时,其返回前调用方的.then就先执行了?
问题根因
你的getUserData函数虽然声明了async,但没有把内部Firestore查询返回的Promise对象return出去:
- 你在
myUserData.get().then()里的return myUserData,只是把值返回给了get()这个Promise本身的回调链,没有传递到外层的getUserData函数的返回值里 - 没有显式return的情况下,async函数会默认返回一个已经resolve为
undefined的Promise,所以调用方的.then()会立刻执行,拿到的就是undefined,这时候get()的异步查询还在执行,所以Here2会比Here1先打印。
修复方案
方案1:直接返回内部的Promise(保持.then写法)
只需要在myUserData.get()前面加个return即可:
async function getUserData(uid: any) { let db = firebase.firestore(); let myUserData = db.collection("users").doc(uid); // 这里加return把内部Promise返回给外层函数 return myUserData.get().then((doc: any) => { if (doc.exists) { let documentData = doc.data().tags let myUserData: userDataType = {}; myUserData.tags = Object.keys(documentData).map(key => <IonItem> <IonLabel>{key} : {documentData[key]}</IonLabel> </IonItem> ) console.log("Here 1: ", myUserData); return myUserData; } else { console.log("No such document!"); return null; } }).catch((error: any) => { console.log("Error getting document:", error); throw error; // 抛出错误让调用方可以catch处理 }); }
方案2:用async/await写法(更简洁,避免嵌套回调)
既然已经使用了async语法,更推荐用await代替.then链式写法,逻辑更清晰:
async function getUserData(uid: any) { try { let db = firebase.firestore(); let userDocRef = db.collection("users").doc(uid); const doc = await userDocRef.get(); // 等待查询结果返回 if (doc.exists) { let documentData = doc.data().tags let myUserData: userDataType = {}; myUserData.tags = Object.keys(documentData).map(key => <IonItem> <IonLabel>{key} : {documentData[key]}</IonLabel> </IonItem> ) console.log("Here 1: ", myUserData); return myUserData; } else { console.log("No such document!"); return null; } } catch (error) { console.log("Error getting document:", error); throw error; } }
两种方案修改完成后,调用方的Here 2会等待异步查询完成后再执行,就能拿到正确的返回值。
内容的提问来源于stack exchange,提问作者esafresa
相关产品推荐
相关产品推荐

