我在下面有async
函数:
async LoadEditForm() {
const { default : EditHero } = await import('./EditHero');
this.setState({ lazyEditHero: EditHero })
}
它在这里被称为:
handleEnableAddMode = async () => {
await this.LoadEditForm();
this.setState({
addingHero: true,
selectedHero: { id: '', name: '', saying: '' }
});
}
我对上面的代码有疑问:
await this.LoadEditForm();
函数中的这一行:handleEnableAddMode
,是否会阻止该函数?换句话说,this.setState(...)
函数会立即被调用,还是等待await
调用完成。
async/await
的概念是允许你以同步方式编写异步代码。这让我很困惑。有人可以澄清吗?答案 0 :(得分:2)
通常await
会一直保持,直到收到成功结果,因为承诺已“解决”,或者由于承诺被“拒绝”而遇到错误。
如果这两个事件都没有发生,那么您的承诺就会被破坏,而await
可能永远不会完成。
答案 1 :(得分:2)
当您调用Asyc函数时,它将返回一个promise,每当您在异步函数中返回一个值时,您的promise将被解析,如果您抛出异常,您的承诺将被拒绝。另一方面,await
表达式暂停执行异步函数并等待传递的Promise的解析,然后恢复异步函数的执行并返回已解析的值。
根据Mozile文档中提供的样本:
function getProcessedData(url) {
return downloadData(url) // returns a promise
.catch(e => {
return downloadFallbackData(url) // returns a promise
})
.then(v => {
return processDataInWorker(v); // returns a promise
});
}
async function getProcessedData(url) {
let v;
try {
v = await downloadData(url);
} catch(e) {
v = await downloadFallbackData(url);
}
return processDataInWorker(v);
}
在您的情况下,您的setState将无法执行,直到您的await this.LoadEditForm();
成为完成状态。但问题是你没有catch
可能拒绝你的承诺。因此,如果函数b被拒绝,那么无论如何都会执行你的setState。
所以你必须在try ... catch
语句中包装await函数和以下行。
答案 2 :(得分:2)
在这一行:await this.LoadEditForm();在handleEnableAddMode函数中,它是否阻止该函数?换句话说,会立即调用this.setState(...)函数,还是等待await调用完成。
其中一个不是另一个“换句话说”。
它没有阻止,它等待。控件将返回异步函数的调用者。当等待的承诺被解决或拒绝时,等待功能将恢复。
https://jsfiddle.net/7yxhqoo4/有一个简单的例子,因此:
function resolveAfterHalfSecond() {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, 500);
});
}
async function f1() {
$("div").append("<p>before await</p>");
await resolveAfterHalfSecond();
$("div").append("<p>after await</p>");
}
function test()
{
$("div").append("<p>before call async function</p>");
f1();
$("div").append("<p>after call async function</p>");
}
$(test);
立即输出如下:
调用异步函数之前
在等待之前
调用异步函数后
半秒后,看起来像是
调用异步函数之前
在等待之前
调用异步函数后
在等待之后。
当await
在f1()
中被点击时,它没有阻止,但立即返回test()
并完成了该功能。当承诺得到解决后,f1()
恢复了。