รอจนกระทั่ง firebase โหลดข้อมูลเสร็จ (vue) / 'await' ไม่ทำงาน
ในแอป vue ของฉันฉันกำลังดึงข้อมูลบางอย่างจากcreated
firebase ใน-hook ฉันต้องการให้โค้ดดังกล่าวถูกดำเนินการในภายหลังหลังจากโหลดข้อมูลเสร็จแล้ว แต่ฉันไม่สามารถทำให้มันทำงานได้
นี่คือรหัสของฉัน:
<template>
<div>
<h1>Test 2</h1>
</div>
</template>
<script>
import { institutesCollection } from '../firebase';
export default {
name: 'Test2',
data() {
return {
settings: null,
}
},
async created() {
await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
await function(doc) {
this.settings = doc.data();
console.log(this.settings);
}
)
console.log('Done with fetching Data');
console.log(this.settings)
},
methods: {
}
}
</script>
แต่หนึ่งคอนโซล'Done with fetching Data'
จะปรากฏขึ้นก่อนจากนั้นnull
(เนื่องจากthis.settings
ยังคงอยู่null
) และหลังจากนั้นsettings
จะพิมพ์Objekt เท่านั้น แต่ฉันต้องthis.settings
ถูกกำหนดไว้ที่นั่น (ไม่ใช่null
อีกต่อไป) เพื่อทำงานกับที่นั่น
สิ่งที่ฉันพยายามจนถึงตอนนี้:
- รอคอย
- การเพิ่มไฟล์
parameter
- การเพิ่มรหัสในภายหลังในไฟล์
then()
ไม่มีอะไรทำงาน
คำตอบ
onSnapshot()วิธีการไม่ได้เป็นวิธีการที่ไม่ตรงกัน ตามที่อธิบายไว้ในเอกสารคือ "แนบฟังDocumentSnapshot
เหตุการณ์"
ดังนั้นคุณควรใช้หากคุณต้องการตั้งค่า Listener ต่อเนื่องให้กับเอกสาร Firestore: หากมีการเปลี่ยนแปลงบางอย่างในเอกสาร (เช่นฟิลด์ได้รับค่าใหม่) ตัวฟังจะถูกทริกเกอร์ โปรดทราบว่า "การโทรครั้งแรกโดยใช้การโทรกลับที่คุณระบุจะสร้างสแนปชอตของเอกสารทันทีพร้อมกับเนื้อหาปัจจุบันของเอกสารเดียว" (ดูเอกสาร )
คุณได้รับข้อมูลเอกสาร Firestore เฉพาะในฟังก์ชันการโทรกลับที่คุณส่งผ่านไปonSnapshot()
ดังต่อไปนี้:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
ดังที่ Nilesh Patel กล่าวไว้โปรดทราบว่าคุณต้องใช้ฟังก์ชันลูกศรเพื่อใช้thisในการโทรกลับนี้ นอกจากนี้ยังทราบว่าcreated
ฟังก์ชั่นไม่จำเป็นต้องเป็น async
สุดท้ายโปรดทราบว่าเป็นแนวทางปฏิบัติที่ดีในการเรียกใช้ฟังก์ชันยกเลิกการสมัครที่ส่งคืนโดยonSnapshot()
เมื่อคุณทำลายคอมโพเนนต์ Vue.js ใช้beforeDestroy
ตะขอดังต่อไปนี้:
// ...
data() {
return {
settings: null,
firestoreListener: null
}
},
created() {
this.firestoreListener = institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
},
beforeDestroy() {
if (this.firestoreListener) {
this.firestoreListener();
}
},
ในทางกลับกันหากคุณแค่ต้องการอ่านข้อมูลเอกสารเท่านั้น ONCEใน Vue.js hook ที่สร้างขึ้นคุณควรใช้get()วิธีการดังต่อไปนี้:
async created() {
const doc = await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').get();
if (doc.exists) {
this.settings = doc.data();
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}
โปรดทราบว่าในกรณีนี้created
ฟังก์ชันต้องเป็นasync
เนื่องจากget()
เป็นแบบอะซิงโครนัส
รายละเอียดเพิ่มเติมเกี่ยวกับความแตกต่างระหว่างget()
และonSnapshot()
ในคำตอบ SOนี้
ลองใช้ฟังก์ชันลูกศร
async created() {
await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
doc => {
this.settings = doc.data();
console.log(this.settings);
}
)
console.log('Done with fetching Data');
console.log(this.settings)
},