简体   繁体   中英

Use try-catch insetead of then-response

Is it's possible to rewrite next code with try-catch? I have heard that modern JS support it.

{
  // GET /someUrl
  this.$http.get('/someUrl').then(response => {

    // get body data
    this.someData = response.body;

  }, response => {
    // error callback
  });
}

Yes, by try catch I assume you are referring to async/await introduced in ES6. It's worth bearing in mind that async/await only works on promise objects and performs exactly the same function but just provides you a more synchronous way to write your code that is (in most situations) easier to read.

Using async await the promise will resolve and return that value and then proceed to the next line of code, any exceptions can be handled in a catch block like so:

const someFunc = async () => {
    try {
        const response = await this.$http.get('/someUrl');
        console.log(response);
    } catch(err){
        // Error handling
        throw new Error(err);
    }
}

While many may point you to async / await so you can use the actual try / catch keywords, I think it's more important to understand the code you have and make an informed decision. Most importantly, promises already handle the try / catch for you. Lets dive in.

In this code, you are dealing with promises.

goDoSomething().then(callThisFunctionWithResultsWhenDone);

One of my favorite properties of Promises are that they already handle try / catch for you.

goDoSomething()
  .then(doSomethingThatThrows)
  .catch(doSomethingWithYourError)
  .then(otherwiseKeepGoing)

Notice I used the .catch instead of passing an error handler in the same line. The inline error handler doesn't do what you may expect so I avoid it. Using .catch() allows you to intelligently handle asynchronous errors by short-circuiting a series of operations or handling errors from a series of steps individually without breaking out of the pipeline.

goDoSomething()
  .then(throwError)
  .then(thisIsSkipped)
  .then(thisToo)
  .catch(handleErrorButDontRethrow)
  .then(doThisWithOrWithoutError)
  .then(finishUp)

I always like to think of this style as a pipeline. Each catch statement catches any errors above it going up to the previous catch .

So, in your case:

$http.get(...)
  .catch(handleRequestError)
  .then(process)
  .catch(handleProcessingError)

This would handle all possible errors but usually to handle the request error you actually would skip the processing step so then:

$http.get(...)
  .then(process)
  .catch(handleProcessingError)

Likewise, whatever calls this block may just want to skip the next block if the processing failed. Then you are left with:

$http.get(...)
  .then(process)

If you find yourself re-throwing then maybe you should remove the catch and let it bubble.

IMO this is much more idiomatic JS code. The style introduced with async / await is a bit more familiar if you learned other languages first but it brings a very imperative feeling with it. In order to have the flexibility to handle each async operation individually your async / await code would need to look like this:

let intermediateStateStorage;

try {
  intermediateStateStorage = await goDoSomething();
} catch {
  handleThis();
} 

try {
  intermediateStateStorage = await process(intermediateStateStorage);
} catch {
  handleThisOne();
}

This seems verbose compared to:

goDoSomething()
  .catch(handleThis)
  .then(process)
  .catch(handleThisOne)

Neither are bad and I obviously have preference but I thought you'd like to know what you are dealing with so you can make an informed decision.

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