[英]How to use async await using functions
我在 Nodejs 上使用 express 制作了 api。
但我不确定我是否很好地使用了异步等待。
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
});
}
}
在这一行中,如果我输入“await”,效果是否良好? 还是由于我完全错误地使用了异步等待而导致结果相同?
result = await searchJibun(query);
result = searchJibun(query);
非常感谢您的阅读。
两者之间肯定有区别:
result = await searchJibun(query);
result = searchJibun(query);
为简单起见,将await
视为一个特殊的 function 从 Promise 解包值,并将值async
打包到 Promise 中。
在我谈论这两个语句有何不同之前,您需要了解async
pack 的价值。
为了让事情更清楚,我将使用 TypeScript 来解释这个概念。
假设您有一个将数字翻倍的 function。
function double_v1(x: number) {
return x * 2;
}
上面 function 的返回类型将是number
。 因此,从类型系统的角度来看,以下表达式是有效的。
double_v1(2) + 3
但是,如果您将async
放在 function 前面,则返回类型将更改为Promise<number>
,即使您没有在代码中的任何位置提及Promise
一词。
async function double_v2(x: number) {
return x * 2;
}
本质上,上面的代码与下面的代码是等价的:
function double_v2(x: number) {
return Promise.resolve(x * 2);
}
并且下面的表达式将是无效的,因为你不能用 Promise 添加数字。
double_v2(2) + 3 // type error
如前所述, await
用于从 Promise 中解压值。 这意味着如果表达式的类型为Promise<T>
,则await
会将表达式解包为T
类型。
例如, double_v2
function 的返回类型为Promise<number>
,因此result
的类型为number
。
const result = await double_v2(3)
如果从语句中删除await
, result
类型将改为Promise<number>
。
但是,请注意,反过来是不正确的。 如果你await
一个非 Promise 表达式,你将返回相同的类型,这意味着下面的两个语句是等价的,因为double_v1
的返回类型不是 Promise 而是数字。
// Equivalent
result = await double_v1(3)
result = double_v1(3)
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>
async
和await
实际上是基于提升(又名打包)的概念。 在这种情况下, async
是lift , await
是unlift 。
在 arrays 的情况下,方括号是lift ,索引运算符是unlift 。
例如, 2
的类型是number
,但是当你用像这样的方括号[2]
将它括起来时,你会将类型提升为Array<number>
。
要解除数组,您可以使用像这样的索引运算符[2][0]
,这个表达式将是number
的类型。
在Promise
的情况下, .resolve
是lift , .then
是unlift 。 例如,您可以通过编写Promise.resolve(e)
将类型为T
的表达式e
的类型提升为Promise<T>
,然后您可以使用myPromise.then(e => {...})
取消它
最后,要真正理解async
和await
,你只需要意识到它们只是提升和解除Promise的语法糖。
在没有糖的世界中,上述操作本可以以更统一的风格编写。
// Arrays
myArray = liftAsArray(1, 2, 3)
firstValue = unliftArray(myArray, 0)
// Promises
myPromise = liftAsPromise(1)
value = unliftPromise(myPromise)
尽管这种编写代码的风格是一致的,但它更冗长,因此更难快速阅读。
P/S: async/await
不是纯粹的语法糖,它们的存在是为了让编译器对你的代码执行一些魔法,这就是为什么使用async/await
和Promises
之间存在性能差异的原因
只要您的searchJibun()
function 是用async
定义的,您就需要等待带有await
的响应
在您的异步函数中,您将不得不使用await
来接收您的 api 响应
我建议您阅读这篇文章以更好地理解
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.