我以为我了解如何使用 async 和 await,直到看到以下代码片段。
所以有一个 onInput 事件处理函数附加到电影输入文本框。其中称为 fetchData 异步函数,它使用 await 关键字来等待来自 axios.get 函数的结果。
我的问题是,为什么我们需要使 onInput 函数也异步?我的意思是,fetchData 函数是异步的。这意味着,它将等到 axios.get 被解析,并且执行将暂停直到 axios.get 被解析。所以当行 const movies = fetchData(event.target.value);执行,将执行 fetchData 函数,该函数将在 await axios.get 语句上暂停。那么为什么我们需要在调用 fetchData 时使用 await 并使 onInput 异步??
const fetchData = async(searchTerm)=>{
const results = await axios.get('http://www.omdbapi.com/', {
params:{
apikey:'d9835cc5',
s: searchTerm
}
});
return results.data.Search;
}
const movieInput = document.querySelector('input');
const onInput = async event => {
const movies = await fetchData(event.target.value);
console.log(movies);
}
movieInput.addEventListener('input', onInput);
答案 0 :(得分:3)
我的意思是,fetchData 函数是异步的。这意味着,它会等到 axios.get 被解析,然后执行将暂停,直到 axios.get 被解析。
这个概念隐藏了很多可能令人困惑的细节,例如使用回调函数恢复暂停的执行。
async
函数不会暂停调用者的执行。
相反,它们返回一个承诺,该承诺将使用执行 async
函数体在语法上返回的值进行解析。需要明确的是,显然从 async
函数体内返回的值不会直接返回给调用者 - 调用者会得到一个承诺。
执行时,await
operator 设置回调,以便其操作数承诺何时解决。在将当前执行上下文存储在内存中并返回到事件循环之前,它有效地调用其 promise 操作数的 then
方法以提供一组 onfulfilled
和 onrejected
回调。
当它收到来自 promise 结算的回调时,await
运算符会恢复它之前保存的执行上下文。如果等待的承诺被拒绝,await
会抛出拒绝原因。如果已完成,await
将继续执行并返回作为执行 await
运算符的结果的承诺的已完成值。
现在历史上 await
从来都不是保留关键字 - 在 ES3 中没有提及,在 ES6 (ECMAScript 2015) 中未来保留关键字,而是在 2021 年 5 月的 ECMAscript 当前草案中的保留字。
因此,为了保持与网络代码的兼容性,await
仅在出现在 async
函数中时才被识别为运算符 - 将其保留为 async
之外的标识符函数体。
同样,async
关键字在历史上也不是保留的,但通过要求将其用于在以前版本的 JavaScript 中会产生意外标识符错误的位置,可以在没有可比性问题的情况下引入。含义在 function
关键字之前或箭头函数表达式之前。
最后,您需要将 onInput
声明为 async
函数,因为 await
在其主体中用作运算符。如果没有 async
声明,await
将被视为标识符而不是运算符的名称。
附带说明,onInput
返回的承诺被丢弃,并可能在当前形式中生成未捕获的承诺拒绝错误。
为了回答“为什么 await
完全需要在 onInput
函数中使用?”这个稍微不同的问题,从 fetchData
返回的值是一个挂起的承诺。为了将movies
设置为results.data.Search
内获得的fetchData
值,需要等待返回promise的fulfiled值。使用 async/await
是这样做的一种方法。另一种方法是通过调用 fetchData
方法向从 then
返回的承诺添加履行处理程序。
答案 1 :(得分:1)
您在 await
中使用了 inInput
运算符。 JavaScript 规则是使用 await
的函数必须是异步的,因此 inInput
也必须是异步的。看看这个答案:https://stackoverflow.com/a/56685416/13357440
此外,MDN 有有用的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
答案 2 :(得分:0)
通常,您希望在程序的其余部分运行时执行 API 调用,因此 onInput
将是异步的。此外,javascript 要求 await 位于 async 函数内,因此代码也只是遵循其标准和规则。通常,一旦顶级是异步的,它内部的所有内容都只是遵循该结构。可以在 here 中找到更多信息。