最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to do something 'on success' in an Async Function using Try and Catch? - Stack Overflow

programmeradmin0浏览0评论

I have an async function that posts data to Firebase Firestore. It works, apart from I need it to do some things after the data has been posted, or 'on success'.

In the code below I'm trying to 'setLoading' to false after the data has been posted to Firestore. The data does get posted, but the loading value remains true. Can anyone see what is wrong with my code, please? I want to do some other things apart from change the value of 'loading', but I'm just using this one instance as an example here.

async function uploadData(e) {

    e.preventDefault()

    try {
        setLoading(true)
        return await useFireStore
            ...
    }

    catch {
        setError('Post failed')
    }

    setLoading(false)  // this isn't working

}

Cheers, Matt

I have an async function that posts data to Firebase Firestore. It works, apart from I need it to do some things after the data has been posted, or 'on success'.

In the code below I'm trying to 'setLoading' to false after the data has been posted to Firestore. The data does get posted, but the loading value remains true. Can anyone see what is wrong with my code, please? I want to do some other things apart from change the value of 'loading', but I'm just using this one instance as an example here.

async function uploadData(e) {

    e.preventDefault()

    try {
        setLoading(true)
        return await useFireStore
            ...
    }

    catch {
        setError('Post failed')
    }

    setLoading(false)  // this isn't working

}

Cheers, Matt

Share Improve this question edited Jan 11, 2021 at 15:36 Frank van Puffelen 601k85 gold badges890 silver badges860 bronze badges asked Jan 11, 2021 at 15:13 Ray PurchaseRay Purchase 7623 gold badges19 silver badges47 bronze badges 2
  • Do useFireStore.then(...) if I understand you need to use promises. – Mindaugas Nakrosis Commented Jan 11, 2021 at 15:17
  • 2 @MindaugasNakrosis - There's no reason to use .then above. It's an async function. – T.J. Crowder Commented Jan 11, 2021 at 15:21
Add a ment  | 

4 Answers 4

Reset to default 3

If you want something to happen on success, you just place is below your await. If you want it to happen no matter what, you can use the finally block.

try {
  setLoading(true)
  const result = await useFireStore;

  // logic here to run on success

  return result;
}
catch {
  setError('Post failed')
}
finally{
  // logic here to always run

  setLoading(false); 
}

The issue is that you're using return in your try catch. This is no different from when you're using try/catch and return in a non-async function. (By design.)

Typically you'd use finally for this:

async function uploadData(e) {

    e.preventDefault()

    try {
        setLoading(true)
        return await useFireStore/*...*/;
    }
    catch {
        setError('Post failed')
    }
    finally {
        setLoading(false)  // this isn't working
    }
}

Note that the await in the above is important. There's no need for return await somePromise if it's at the top level of your function code (just use return somePromise), but the await can make a big difference if it's not at the top level, which is the case here. So you do need that await.


Side note: As written, your function fulfills its promise with the result of the useFireStore call if it works, but with undefined if it doesn't work. If useFireStore can return undefined, that means code using your function has no idea whether the operation succeeded or failed. (But if useFireStore doesn't every return undefined on success, then code using your function could tell the difference.)

You used return inside try block so it is returning without setting the loading status to false. Also, you should set the loading status to false on error case as well, so your code should look like:

async function uploadData(e) {
    e.preventDefault()
    
    setLoading(true)
    
    try {
        await useFireStore
    }
    catch {
        setError('Post failed')
    }
    finally {
        setLoading(false)
    }
}

You're returning after the request is created, if you need to use the response, store it in the variable instead of returning, also if you want to make sure any code is executed after the request was pleted ( successful or unsuccessful), use the finally block

async function uploadData(e) {

  e.preventDefault()

  try {
    setLoading(true)
    const response = await useFireStore(); // don't return here
    // use the response var if it request returns any data 
  } catch {
    setError('Post failed')
  } finally {
    setLoading(false) //move the setLoading here    
  }
}
发布评论

评论列表(0)

  1. 暂无评论