我在Node.js上使用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);
非常感谢您的阅读。
答案 0 :(得分:2)
两者之间肯定有区别
result = await searchJibun(query);
result = searchJibun(query);
为简单起见,将await
视为从Promise拆包价值的特殊功能,并将async
打包为Promise的价值。
在讨论这两个语句有何不同之前,您需要了解async
打包值的方式。
为了使事情更清楚,我将使用TypeScript解释这个概念。
假设您有一个将数字加倍的函数。
function double_v1(x: number) {
return x * 2;
}
上面函数的返回类型将为number
。因此,从类型系统的角度来看,以下表达式是有效的。
double_v1(2) + 3
但是,即使在代码中的任何地方都没有提到async
字样,如果将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
函数的返回类型为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
函数用async
关键字标记,这意味着它必须返回Promise,因此在调用await
时使用searchJibun
将解压缩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 。
对于数组,方括号为 lift ,而索引运算符为 unlift 。
例如,2
的类型为number
,但是当您用[2]
这样的方括号将其包围时,您将 lift 变成{ {1}}。
要取消一个数组,请使用像Array<number>
这样的索引运算符,该表达式的类型为[2][0]
。
在number
的情况下,Promise
是 lift ,而.resolve
是 unlift 。例如,您可以通过编写.then
将类型e
的表达式T
的类型提升为Promise<T>
,然后用Promise.resolve(e)
< / p>
最后,要真正理解myPromise.then(e => {...})
和async
,您只需要意识到它们只是 lifting 和 unlifting 承诺。
在一个无糖的世界中,上面的操作原本可以用更统一的样式编写。
await
尽管这种编写代码的方式是一致的,但它更加冗长,因此难以快速阅读。
P / S:// Arrays
myArray = liftAsArray(1, 2, 3)
firstValue = unliftArray(myArray, 0)
// Promises
myPromise = liftAsPromise(1)
value = unliftPromise(myPromise)
并不是纯粹的语法糖,它们存在的目的是使编译器可以对您的代码执行一些魔术,这就是为什么在使用async/await
和async/await
之间存在性能差异的原因< / p>
答案 1 :(得分:1)