简体   繁体   中英

chaining await with .then and try catch syntax

I have a submit function

const onSubmit = async (creditCardInput) => {
const { navigation } = this.props;
this.setState({ submitted: true });
let creditCardToken;

try {
  creditCardToken = await getCreditCardToken(creditCardInput);
  if (creditCardToken.error) {
    this.setState({ submitted: false});
    return;
  }
} catch (e) {
  this.setState({ submitted: false });
  return;
}


try {
  const obj = await subscribeUser(creditCardToken);
  console.log('returned obj', obj);
  try {
    const docRef = await this.db.collection("users").doc(this.user.email).set({
      id: this.user.uid,
      subscriptionId: obj.customerId,
      active: true
    });
    console.log("Document written with ID: ", docRef);
    this.navigateToScreen('HomeScreen');
  } catch (e) {
    console.log("Error adding document: ", e);
  }
} catch (error) {
  console.log('catch error', error);
  this.setState({ submitted: false, error: SERVER_ERROR, message: error });
}  
};

This is working as suspected - when this.db.collection call fails the catch is implemented meaning it logs out "Error adding document: ", e see code snippet below

  try {
    const docRef = await this.db.collection("users").doc(this.user.email).set({
      id: this.user.uid,
      subscriptionId: obj.customerId,
      active: true
    });
    console.log("Document written with ID: ", docRef);
    this.navigateToScreen('HomeScreen');
  } catch (e) {
    console.log("Error adding document: ", e);
  }

However when I implement the subscribe user function in a different manner (see below) I'm no longer using try catch but rather.then on await the inner function ends up failing and the outside catch statement is executed meaning it logs out console.log('catch error', error); when it should be logging out console.log("Error adding document: ", errors); why is that? shouldn't they work in the same way meaning the code snippet above and below should work in the same manner see code below

await subscribeUser(creditCardToken).then((obj)=> {
this.db.collection("users").doc(this.user.email).set({
    id: this.user.uid,
    subscriptionId: obj.customerId,
    active: true
}).then((docRef) => {
    console.log("Document written with ID: ", docRef);
    this.navigateToScreen('HomeScreen');
}).catch((errors) => {
    console.log("Error adding document: ", errors);
});
}).catch((error) => {
    console.log('catch error', error);
    this.setState({ submitted: false message: error });
});

Just an added note when this.db.collections resolves successfully the.then executes the way it should meaning it logs out with console.log("Document written with ID: ", docRef) however like I said before if it's rejected the outer catch is executed and not the inner catch

Also adding return to the this.db.collection function and removing await has no effect on outcome

There are two ways to handle this - convert your set function to use async/await syntax, or return your set function to the subscribeUser function's next then statement. I'll show both, but I prefer the second as I don't like mixing async/await with then/catch.

const tempThis = this
subscribeUser(creditCardToken).then((obj)=> {
  // RETURN this promise and you'll get it in the next then statement
  return tempThis.db.collection("users").doc(tempThis.user.email).set({
    id: tempThis.user.uid,
    subscriptionId: obj.customerId,
    active: true
  })
}).then((docRef) => {
  console.log("Document written with ID: ", docRef);
  this.navigateToScreen('HomeScreen');
}).catch((errors) => {
  // This will catch the errors from subscribeUser AND from the set function
  console.log("Error adding document: ", errors);
});

or using just async/await

try {
  const obj = await subscribeUser(creditCardToken)
  const docRef = await this.db.collection("users").doc(this.user.email).set({
    id: this.user.uid,
    subscriptionId: obj.customerId,
    active: true
  })
  console.log("Document written with ID: ", docRef);
  this.navigateToScreen('HomeScreen');
} catch (error) {
  // Handle your errors
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM