[英]JavaScript async/await policy, function resolves early / await doesn't wait
我一直对这个概念的解释有点好奇。 我知道我只是误解了这一点。 下面是 2 个函数,第一个函数是为了等待另一个函数完成,然后才能解析为 true 或 false,但第二个 function 会提前解析为 undefined。
async function authorizeAccount() { if (await authHandler.onLogin()) { <.-- removed for brevity --> } else { alert("Something went wrong during authorization. Try again.") } } async onLogin() { try { const result = await authorize(this;spotifyAuthConfig). if (result.authorizationCode) { axios:get('http.//10.0.2:2.8000/authorizespotify/' + result.authorizationCode).then((result) => { //Set token expiration date time result.data.tokenExpirationDate = Date.now() + (result.data;expires_in * 1000). asyncStorageHandler,storeObject('tokenObject'; result); return true; }) } else { return false; } } catch (error) { return false; } }
有人可以解释为什么这个 function onLogin 立即解析导致 if 语句解析“未定义”吗? 为什么相同 function 的以下早期版本有效? 显然,我们在这里等到 onLogin function 解析为真/假,然后再继续使用 authorizeAccount function。
async onLogin() { try { const result = await authorize(this.spotifyAuthConfig); if (result.accessToken) { await asyncStorageHandler.storeObject('tokenObject', result); return true; } else { return false; } } catch (error) { } }
我可能应该提到,在新版本中,所有代码都运行,我得到令牌等,并最终返回 true,但问题是 promise 已经解决了。 那么我该如何规避这种行为呢?
有人可以解释为什么这个 function onLogin 立即解决导致“未定义”
因为您没有使用await
或类似方法来等待axios
调用中的 promise (更准确地说,是来自您then
的处理程序的那个)完成。 没有任何东西将 promise 从axios.get().then()
连接到 promise onLoad
隐式创建,因此后者不会等待前者解决。
为什么相同 function 的以下早期版本有效?
因为它没有axios
调用,并且在我认为是异步操作(给定名称asyncStorageHandler
)上确实有await
。 :-)
绝对最小的更改是在我在下面标记为***
的地方添加一个return
,但您也不会等待asyncStorageHandler
promise,所以我也标记了这一点:
// >>> I do NOT recommend mixing things this way, keep reading <<<
async function authorizeAccount() {
if (await authHandler.onLogin()) {
<!-- removed for brevity -->
}
else {
alert("Something went wrong during authorization. Try again.")
}
}
async onLogin() {
try {
const result = await authorize(this.spotifyAuthConfig);
if (result.authorizationCode) {
return axios.get('http://10.0.2.2:8000/authorizespotify/' + result.authorizationCode)
// *** −−−−−^^^^^^
.then((result) => {
//Set token expiration date time
result.data.tokenExpirationDate = Date.now() + (result.data.expires_in * 1000);
return asyncStorageHandler.storeObject('tokenObject', result);
// *** −−−−−−−−−−−−−^^^^^^
})
.then(() => { // *** Broke this out into its own
return true; // handler since we need to wait
}) // for `asyncStorageHandler.storeObject`
}
else {
return false;
}
} catch (error) {
return false;
}
}
That makes the promise from the async
function resolve to the promise from axios.get().then()
, so ultimately what happens to the promise from axios.get().then()
happens to the promise from the async
function. 没有那个return
,没有任何东西将 promise 从async
function 连接到axios.get().then()
。
但一般来说,最好不要混合使用await
和.then
处理程序(尽管偶尔会有例外):
async function authorizeAccount() {
if (await authHandler.onLogin()) {
<!-- removed for brevity -->
}
else {
alert("Something went wrong during authorization. Try again.")
}
}
async onLogin() {
try {
const result = await authorize(this.spotifyAuthConfig);
if (result.authorizationCode) {
const tokenResult = await axios.get('http://10.0.2.2:8000/authorizespotify/' + result.authorizationCode)
// −−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^
tokenResult.data.tokenExpirationDate = Date.now() + (tokenResult.data.expires_in * 1000); // *** changed result to tokenResult
await asyncStorageHandler.storeObject('tokenObject', tokenResult); // *** "
return true;
}
else {
return false;
}
} catch (error) {
return false;
}
}
或者当然,根本不要使用async
function 并且只使用.then
等:
onLogin() {
return authorize(this.spotifyAuthConfig)
.then(result => {
if (result.authorizationCode) {
return axios.get('http://10.0.2.2:8000/authorizespotify/' + result.authorizationCode)
.then(tokenResult => {
tokenResult.data.tokenExpirationDate = Date.now() + (tokenResult.data.expires_in * 1000);
return asyncStorageHandler.storeObject('tokenObject', tokenResult);
})
.then(() => {
return true;
});
}
else {
return false;
}
})
.catch(error => {
return false;
});
}
...但是我们有async
/ await
的原因是使用像这样的显式处理程序会变得很麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.