繁体   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