TypeScript从Promise取值及Ionic3+Firebase中this.db找不到问题求助
Hey there! Let's break down your two questions with practical examples tailored to your tech stack (TypeScript, Ionic 3, Firebase):
Promises are asynchronous, so you can't just "extract" the value synchronously like a regular variable. There are two main, idiomatic ways to handle this:
Using .then() chains
This is the classic approach for working with promises. You attach a .then() handler to process the resolved value, and a .catch() handler to catch errors:
// Example: A function that returns a Promise function fetchUserKey(): Promise<string> { return new Promise((resolve) => { // Simulating an async operation (like Firebase auth) setTimeout(() => resolve("auto-generated-user-key-123"), 1000); }); } // Get the value with .then() fetchUserKey() .then((userKey) => { console.log("Got user key:", userKey); // Use userKey for your subsequent requests here }) .catch((error) => { console.error("Failed to get user key:", error); });
Using async/await (cleaner for sequential code)
If you prefer code that reads more like synchronous logic, use async/await. Just remember:
- You can only use
awaitinside a function marked withasync - Always wrap
awaitcalls in atry/catchblock to handle errors
async function processUserKey() { try { const userKey = await fetchUserKey(); console.log("Got user key:", userKey); // Use userKey for your Firebase requests here } catch (error) { console.error("Failed to get user key:", error); } } // Call the async function processUserKey();
This almost always boils down to this context issues. In traditional function callbacks, this doesn't refer to your Ionic component/service instance anymore. Here are 3 easy fixes:
Fix 1: Use Arrow Functions (most recommended)
Arrow functions inherit the this context from the surrounding code, so your component's this.db will be accessible:
// Assume you have a Firebase auth promise that returns a user with uid (your userKey) firebase.auth().createUserWithEmailAndPassword(email, password) .then((userCredential) => { const userKey = userCredential.user.uid; // Auto-generated user key // Now this.db works because arrow function preserves the context this.db.collection('users').doc(userKey).set({ email: email, createdAt: new Date() }); }) .catch((error) => { console.error("Auth failed:", error); });
Fix 2: Save this to a variable before the promise
If you prefer traditional functions, store the component's this in a variable (like self or that) to use inside the callback:
const self = this; // Save component's this to a variable firebase.auth().createUserWithEmailAndPassword(email, password) .then(function(userCredential) { const userKey = userCredential.user.uid; self.db.collection('users').doc(userKey).set({ /* your data */ }); });
Fix 3: Bind this to the callback function
Use .bind(this) to explicitly set the this context for the callback:
firebase.auth().createUserWithEmailAndPassword(email, password) .then(function(userCredential) { const userKey = userCredential.user.uid; this.db.collection('users').doc(userKey).set({ /* your data */ }); }.bind(this)) // Bind component's this to the function .catch((error) => { console.error("Auth failed:", error); });
Also, double-check that you've properly injected AngularFireDatabase in your component's constructor (assuming you're using AngularFire2 for Firebase integration):
import { AngularFireDatabase } from 'angularfire2/database'; constructor(private db: AngularFireDatabase) { // this.db is initialized here and ready to use }
内容的提问来源于stack exchange,提问作者Thibaut Chazalon

