简体   繁体   中英

How to use async await using functions

I made an api using express on Nodejs.
But I'm not sure whether I used async await well for it.

module.search = async(req, res) => {
    async function searchJibun(arg) {
        const resultJibun = await axios.get(
          'https://apis.com/code',
          {
            headers: {
              'KEY-ID': process.env.N_KEY_ID,
              'KEY': process.env.N_KEY
            },
            params: {
              query: arg
            }
          }
        );

        return resultJibun;
      }

      const { query } = req.body;
      const searchResult = [];
      let result = '';

      try {
        result = await searchJibun(query);
      } catch (error) {
        return res.status(200).json({
          success: false,
          code: 500,
          msg: 'Internal Server Error(1)',
          err: error
        });
      }
}

In this line, if I type 'await', does it work well? Or the result is same due to my wrong used about async await totally?

result = await searchJibun(query);

result = searchJibun(query);

thank you so much for reading.

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 (aka 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

as long as your searchJibun() function is defined with async you will need to wait for the response with the await

And within your async functions you will have to use the await to receive your api responses

I recommend you read this article to better understand

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