[英]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.