簡體   English   中英

JavaScript 異步/等待策略,function 提前解決/等待不等待

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM