There is definitely a difference between:
result = await searchJibun(query);
result = searchJibun(query);
To make things simple, think of await as a special function to unpacking value from Promise, and async for packing value into Promise.
Before I talk about how those two statements are different, you need to understand how async pack value.
To make things clearer I'm going to explain this concept using TypeScript.
Async
Suppose you have a function that doubles a number.
function double_v1(x: number) {
return x * 2;
}
The return type of the function above will be number. Because of that, the following expression is valid from the perspective of the type system.
double_v1(2) + 3
However, if you put async in front of the function, the return type changes to Promise<number>, even though you did not mention the word Promise anywhere in the code.
async function double_v2(x: number) {
return x * 2;
}
Essentially, the code above is equivalent with the code below:
function double_v2(x: number) {
return Promise.resolve(x * 2);
}
And the following expression will be invalid, because you cannot add numbers with Promise.
double_v2(2) + 3 // type error
Await
As mentioned previously, await is for unpacking value from Promise. It means that if an expression has type of Promise<T>, then await will unpack the expression into type of T.
For example, the double_v2 function has return type of Promise<number>, thus the result will have the type of number.
const result = await double_v2(3)
If you remove await from the statement, the type of result will become Promise<number> instead.
However, note that the other way round is not true. If you await for a non-Promise expression, you will get back the same type, it means that the two statements below are equivalent because the return type of double_v1 is not Promise but number.
// Equivalent
result = await double_v1(3)
result = double_v1(3)
Conclusion
The searchJibun function is mark with async keyword, it means it must return Promise, so using await on invocation of searchJibun will unpack the Promise, thus the following statement is not equivalent.
result = await searchJibun(query); // type of result will be T
result = searchJibun(query); // type of result will be Promise<T>
Extra notes
async and await is actually based on the concept of lifting (a.k.a packing). In this case, async is lift, and await is unlift.
In the case of arrays, the square brackets is lift and the indexing operator is unlift.
For example, the type of 2 is number, but when you surround it with square brackets like this [2] you lift the type to become Array<number>.
To unlift an array, you use the indexing operator like this [2][0], and this expression will the type of number.
In the case of Promise, .resolve is lift and .then is unlift. For example, you can lift the type of an expression e with type T to Promise<T> by writing Promise.resolve(e), and then you can unlift it with myPromise.then(e => {...})
In the end, to really understand async and await, you just have to realise that they are just syntactic sugar for lifting and unlifting Promises.
In a sugarless world, the operations above could have been written in a more uniform style as such.
// Arrays
myArray = liftAsArray(1, 2, 3)
firstValue = unliftArray(myArray, 0)
// Promises
myPromise = liftAsPromise(1)
value = unliftPromise(myPromise)
Although this style of writing code is consistent, it is more verbose and thus harder to be read fast.
P/S: async/await are not purely syntactic sugar, they exists for compiler to perform some magic on your code, that's why there are performance differences between using async/await and Promises
200when you've instead returned code500. Instead, just pass500tores.statusand remove thecodeproperty from the resulting payload.