简体   繁体   English

如何使用函数使用异步等待

[英]How to use async await using functions

I made an api using express on Nodejs.我在 Nodejs 上使用 express 制作了 api。
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?在这一行中,如果我输入“await”,效果是否良好? 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.为简单起见,将await视为一个特殊的 function 从 Promise 解包值,并将值async打包到 Promise 中。

Before I talk about how those two statements are different, you need to understand how async pack value.在我谈论这两个语句有何不同之前,您需要了解async pack 的价值。

To make things clearer I'm going to explain this concept using TypeScript.为了让事情更清楚,我将使用 TypeScript 来解释这个概念。


Async异步

Suppose you have a function that doubles a number.假设您有一个将数字翻倍的 function。

function double_v1(x: number) { 
    return x * 2; 
}

The return type of the function above will be number .上面 function 的返回类型将是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 前面,则返回类型将更改为Promise<number> ,即使您没有在代码中的任何位置提及Promise一词。

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.并且下面的表达式将是无效的,因为你不能用 Promise 添加数字。

double_v2(2) + 3 // type error

Await等待

As mentioned previously, await is for unpacking value from Promise.如前所述, await用于从 Promise 中解压值。 It means that if an expression has type of Promise<T> , then await will unpack the expression into type of T .这意味着如果表达式的类型为Promise<T> ,则await会将表达式解包为T类型。

For example, the double_v2 function has return type of Promise<number> , thus the result will have the type of number .例如, double_v2 function 的返回类型为Promise<number> ,因此result的类型为number

const result = await double_v2(3)

If you remove await from the statement, the type of result will become Promise<number> instead.如果从语句中删除awaitresult类型将改为Promise<number>

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.如果你await一个非 Promise 表达式,你将返回相同的类型,这意味着下面的两个语句是等价的,因为double_v1的返回类型不是 Promise 而是数字。

// 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. searchJibun function 是用async关键字标记的,这意味着它必须返回 Promise,因此在调用searchJibun时使用await将解包 Promise,因此以下语句不等效。

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 ). asyncawait实际上是基于提升(又名打包)的概念。 In this case, async is lift , and await is unlift .在这种情况下, asyncliftawaitunlift

In the case of arrays, the square brackets is lift and the indexing operator is unlift .在 arrays 的情况下,方括号是lift ,索引运算符是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> .例如, 2的类型是number ,但是当你用像这样的方括号[2]将它括起来时,你会将类型提升Array<number>

To unlift an array, you use the indexing operator like this [2][0] , and this expression will the type of number .解除数组,您可以使用像这样的索引运算符[2][0] ,这个表达式将是number的类型。

In the case of Promise , .resolve is lift and .then is unlift .Promise的情况下, .resolvelift.thenunlift 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 => {...})例如,您可以通过编写Promise.resolve(e)将类型为T的表达式e的类型提升为Promise<T> ,然后您可以使用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.最后,要真正理解asyncawait ,你只需要意识到它们只是提升和解除Promise的语法糖。

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 P/S: async/await不是纯粹的语法糖,它们的存在是为了让编译器对你的代码执行一些魔法,这就是为什么使用async/awaitPromises之间存在性能差异的原因

as long as your searchJibun() function is defined with async you will need to wait for the response with the await只要您的searchJibun() function 是用async定义的,您就需要等待带有await的响应

And within your async functions you will have to use the await to receive your api responses在您的异步函数中,您将不得不使用await来接收您的 api 响应

I recommend you read this article to better understand我建议您阅读这篇文章以更好地理解

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM