Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Is it an anti-pattern to run asynchronous callbacks in error catching like this?
await something()
.catch(async (err) => {
console.error(err);
await otherStuff();
});
If your intent is to have that whole expression there never reject - that is, to avoid the need for
try {
await something()
.catch(async (err) => {
// ...
} catch(e) {
// handle
}
Then what you're doing right now isn't safe if there's any chance of the otherStuff call rejecting. If otherStuff might reject, then you should make sure to catch possible errors it throws, eg
await something()
.catch(async (err) => {
console.error(err);
await otherStuff();
})
.catch(handleOtherStuffErrors)
Though having an async function with only a single await isn't that useful - consider instead just returning the Promise:
await something()
.catch((err) => {
console.error(err);
return otherStuff();
})
.catch(handleOtherStuffErrors)
Chaining catches like that is pretty odd, but it's not impossible that that's what one's logic requires, so don't make a blanket statement about whether it's inherently bad.
The way you do it is. In a promise you should return the promise instead of making the callback async and awaiting it.
I don't think it is since you can call .then behind the catch. Sometimes an throw just goes into a diffrent branch of operations but at the end its preference.
await something()
.catch((err) => {
console.error(err);
return otherStuff();
}).then(res => {
// work with data
});
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've become enamored with the async/await syntax for consuming promises since it looks and acts like synchronous code.
Although I see most examples of async/await with named functions, I find that I always write async/await code now in IIFEs, since it is mere syntactic sugar anyway, like this:
btnInOrderElem.onclick = () => {
(async () => {
contentElem.innerHTML = '';
loaderAreaElem.style.display = 'inline';
addLi(await loader.getData());
addLi(await loader.getData());
addLi(await loader.getData());
loaderAreaElem.style.display = 'none';
})();
}
Is there anything I'm missing with this practice? Are there disadvantages to doing this at some point? Is there any reason to create named functions in order to run async/await code?
In your specific example, there's really no difference between any of these:
btnInOrderElem.onclick = async () => { ... }
btnInOrderElem.onclick = () => {
(async () => { ... })()
}
async function onClickHandler() { ... }
btnInOrderElem.onclick = onClickHandler
When you define a function as async, it means Javascript will automatically cause that function to always return a promise, that resolves when it's inner tasks are completed. While the function definitions are different in the above code snippets (some would return a promise while others return undefined), the actual program will behave the same, because the browser ignores whatever is returned from the event handler (usually).
If, however, you were writing a utility function like this:
function getUser() {
(async () => { ... })()
}
// or
async function getUser() { ... }
There is an important difference. The second function will return a promise, so you can await that promise and get the resulting value. The first function will dispatch an async action then return undefined. You can't get a resulting value out of the first, nor can you await it.
Here's an exercise for you.
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
async function waitThenLog(ms, message) {
await wait(ms)
console.log(message)
}
;(async function main() {
await waitThenLog(500, 'Hello World!')
console.log('done')
})()
Above I have a simple program. It'll wait 500ms then log a message, then logs "done". Try changing it so that the waitThenLog() function uses your IIFE idea and see if you can get it to work. You'll find that you will run into some fundamental problems.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Code Block 1
export async function sendToDatabase(order, ownProps) {
const url = `api_url`
await axios.post(url, order).then(
(response) => {
if (response.status == 200){
console.log("response 200")
console.log(response)
return response
}
}
).catch(error => (error))
}
Code Block 2
sendToDatabase(order, ownProps).then(
value => console.log(value)
)
Console Output
response 200
{data: "Order Uploaded", status: 200, statusText: "", headers: {…}, config: {…}, …}
undefined
The function in code block 1 is called in code block 2. I don't really understand why the value returned is undefined, especially since the sendToDatabase() function returns a promise, and the promise should already be resolved in the then block
Also, due to certain constraints of my project, the 2 code blocks cannot be merged, and have to exist separately, hence I am not able to put code block 2 into the .then() block of code block 1
Any form of advice or help will be greatly appreciated!
Normally a comment would be enough for such a question but i would like to post an answer as there are multiple problems in your code.
sendToDatabase function doesn't explicitly returns any value, so the promise returned by it is implicitly fulfilled with the value of undefined.
To fix this problem, you need to explicitly return some value from sendToDatabase function.
Don't mix promise-chaining with async-await syntax. Your sendToDatabase function can be simplified as shown below:
export async function sendToDatabase(order, ownProps) {
const url = `api_url`;
try {
return await axios.post(url, order);
} (error) {
// handle the error
}
}
I have omitted the check for response.status, you could check the status code in the calling code.
Inside the callback function of the catch method, you are returning the error object that was passed to the callback function as an argument; this will implicitly convert promise rejection into promise fulfilment.
To solve the problem, you need to throw the error object instead of returning it.
.catch(error => { throw error });
I suggest that you allow the calling code to catch and handle the error. This means that you should remove the catch block from the sendToDatabase function and add it in the code where you call the sendToDatabase function.
If you add the catch handler in the calling code, then your function could be simplified as shown below:
export async function sendToDatabase(order, ownProps) {
const url = `api_url`;
return axios.post(url, order);
}
(if you are wondering why there is no await keyword before axios.post(...), see this answer which contains an answer to this question.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I've found this sample snippets in this article :
<script>
async function get_data() { // async function
await $.get('https://url.com/one')
await $.get('https://url.com/two')
let res = await $.get('https://url.com/three')
console.log(res)
}
</script>
Which is the promised version of :
<script>
function get_data() {
$.get('https://url.com/one', () => {
$.get('https://url.com/two', () => {
$.get('https://url.com/three', (res) => {
console.log(res)
})
})
})
}
</script>
My question being, in the promised version, can we turn await $.get('https://url.com/one') into await $.get('https://url.com/one') as it is the first promise?
If yes, why would either one of both be considered as best practice?
Thank you in advance
If you want the call to url.com/two to run after url.com/one is done, you have to await the promise returned.. However, if you want all of them to run at the same same time, you can remove the await, and pass the 2 promises into a Promise.all([promise1,promise2, promise3]) which you can await
If you remove the await, it doesn't wait for the resolve or reject response from the promise.
What it does is to skip the expression in thread and continues to fetch the second response.
The first snippet is the best practice because you will get the callback hell for your code. Think about the page where you need to send 20 requests and think about callbacks. No-one can understand what request is sent from where. So with Promises, you can just wait or skip the task (if you skip, it will run in the background). So hierarchy on code structure doesn't change. Another problem is when you need to return the response to the variable. You need to put such a structure.
<script>
function get_data() {
let res = $.get('https://url.com/one', () => {
return $.get('https://url.com/two', () => {
return $.get('https://url.com/three', (res) => {
console.log(res)
return res;
})
})
})
}
</script>
I've been seeing a couple of different patterns for handling errors.
One is like:
let result;
try {
result = await forSomeResult(param);
} catch {
throw new Error();
}
And the other is like:
const result = await forSomeResult(param).catch(() => throw new Error());
I prefer the latter since it looks like a cleaner solution. But I've also heard talks that the first solution is better since there could be some race condition where the .catch doesn't execute before the next command is run.
I was wondering if someone had a technical answer about why one method is better than the other.
First of all, there's no reason to catch and throw or .catch() and throw unless you're going to do something else inside the catch handler or throw a different error. If you just want the same error thrown and aren't doing anything else, then you can just skip the catch or .catch() and let the original promise rejection go back to the caller.
Then, it is generally not recommended that you mix await with .catch() as the code is not as easy to follow. If you want to catch an exception from await, use try/catch around it. .catch() works, it's just not a preferred style if you're already awaiting the promise.
The one technical difference between these two styles:
async function someFunc()
let x = await fn().catch(err => {
console.log(err);
throw err;
});
// do something else with x
return something;
}
And, this:
async function someFunc()
let x;
try {
x = await fn();
} catch(err) {
console.log(err);
throw err;
}
// do something else with x
return something;
}
is if the function fn() you are calling throws synchronously (which it shouldn't by design, but could by accident), then the try/catch option will catch that synchronous exception too, but the .catch() will not. Because it's in an async function, the async function will catch the synchronous exception and turn it into a rejected promise for you automatically for the caller to see as a rejected promise, but it wouldn't get logged or handled in your .catch() handler.
One of the more beneficial cases for try/catch with await is when you have multiple await statements and you don't need to handle errors on any of them individually. Then, you can surround them with one try/catch and catch all the errors in one place.
async function someFunc(someFile) {
let fileHandle;
try {
// three await statements in a row, all using same try/catch
fileHandle = await fsp.open(someFile);
let data = await fsp.read(...);
// modify data
await fsp.write(...)
} catch(err) {
// just log and re-throw
console.log(err);
throw err;
} finally {
// close file handle
if (fileHandle) {
await fileHandle.close();
}
}
}
It depends.
Are you going to be calling multiple asynchronous functions that could error? You can wrap them all in a try/catch and perform common error handling without having to repeat yourself:
try {
result = await forSomeResult(param);
await forSomeOtherResult();
return await finalResult(result);
} catch { //catches all three at once!
throw new Error();
}
Do you only need to handle errors for this one, specific call? The .catch() pattern is fine. There is no race condition to worry about, await waits for the promise to resolve or reject, and this includes all success and failure callbacks attached to the promise. However, in your example, you're catching an error only to throw an empty one - in that case, it may be preferable to simply write this:
const result = await forSomeResult(param);
...and let the error propagate to the caller naturally.
I've seen a mixture of both styles used common enough that I think it's fine either way - they each have a particular strength.
This question already has answers here:
try/catch blocks with async/await
(10 answers)
Closed 5 years ago.
I have an async function that fails:
async function main() {
// fails
throw 'some error';
}
main();
what is the correct way to propagate this exception to end program execution?
Is this:
main().catch(err => { console.log(err); process.exit(1); });
the correct way or is there a better pattern?
There is a better way:
You can listen to the "unhandledRejection" event like so :
process.on('unhandledRejection', error => {
console.log('unhandledRejection', error) //if you want to log the error
process.exit(1);
});
By doing so, you don't have to catch all your async function that may throw. And you save yourself if there is an error in the catch function.
This will remove the unwanted warning.