JavaScript异步/等待策略,函数解析早期/等待不';等不及了

JavaScript异步/等待策略,函数解析早期/等待不';等不及了,javascript,asynchronous,ecmascript-6,async-await,Javascript,Asynchronous,Ecmascript 6,Async Await,我对这个概念的解释一直有点好奇。 我知道我只是误解了这一点。 下面是两个函数,第一个函数意味着在使用true或false解析之前等待另一个函数完成,但是第二个函数使用undefined提前解析 异步函数authorizeAccount(){ if(等待authHandler.onLogin()){ } 否则{ 警报(“授权过程中出现问题。请重试。”) } } 异步onLogin(){ 试一试{ const result=等待授权(this.spotifyauthorconfig); if(结果

我对这个概念的解释一直有点好奇。 我知道我只是误解了这一点。 下面是两个函数,第一个函数意味着在使用true或false解析之前等待另一个函数完成,但是第二个函数使用undefined提前解析

异步函数authorizeAccount(){
if(等待authHandler.onLogin()){
}
否则{
警报(“授权过程中出现问题。请重试。”)
}
}
异步onLogin(){
试一试{
const result=等待授权(this.spotifyauthorconfig);
if(结果授权代码){
axios.get()http://10.0.2.2:8000/authorizespotify/“+结果.授权代码)
。然后((结果)=>{
//设置令牌过期日期和时间
result.data.tokenExpirationDate=Date.now()+(result.data.expires_in*1000);
asyncStorageHandler.storeObject('tokenObject',结果);
返回true;
})
}
否则{
返回false;
}
}捕获(错误){
返回false;
}
}
有人能解释一下为什么这个函数onLogin会立即解析为“undefined”吗

因为您没有使用
wait
或类似工具来等待
axios
调用(更准确地说,是
then
处理程序中的调用)的承诺完成。没有任何东西将axios.get().then()的承诺隐式连接到onLoad创建的承诺,因此后者不会等待前者解决

为什么相同函数的以下早期版本可以工作

因为它没有
axios
调用,并且有
await
关于我假设的异步操作(命名为
asyncStorageHandler
)。:-)

绝对最小的更改是在下面我标记的
***
位置添加一个
返回
,但您也没有等待
异步存储处理器
承诺,因此我也标记了这一点:

// >>> 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;
    }
}
当然,也不要使用
async
函数,只使用

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
的原因是使用这样的显式处理程序可能会很麻烦

有人能解释一下为什么这个函数onLogin会立即解析为“undefined”吗

因为您没有使用
wait
或类似工具来等待
axios
调用(更准确地说,是
then
处理程序中的调用)的承诺完成。没有任何东西将axios.get().then()
的承诺隐式连接到onLoad创建的承诺,因此后者不会等待前者解决

为什么相同函数的以下早期版本可以工作

因为它没有
axios
调用,并且有
await
关于我假设的异步操作(命名为
asyncStorageHandler
)。:-)

绝对最小的更改是在下面我标记的
***
位置添加一个
返回
,但您也没有等待
异步存储处理器
承诺,因此我也标记了这一点:

// >>> 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;
    }
}
当然,也不要使用
async
函数,只使用

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
的原因是,使用这样的显式处理程序可能会很麻烦。

第一个代码片段等待
authHandler.onLogin()
,但是没有
authHandler
,因此该条件立即计算为false。您是否打算让
if(等待这个.onLogin())
,也许?旁注:将拒绝/错误转换为带标志的履行/返回通常是一种反模式。在大多数情况下,调用代码应该知道检查授权的尝试失败了,而不是返回否定结果。第二个代码段是旧版本,因为为了存储客户端机密服务器端,我重写了函数。是的,很抱歉,我忽略了一个事实,这是在一个使用类和组件的react原生项目中,所以这里一切正常。如前所述,我确实获得了令牌,所有这些,函数只是很早就解析了。
axios.get
是异步的。但您不会等待它,也不会在第一个代码片段中从
onLogin
返回任何内容。您必须执行
返回axios.get(…
derpirscher.I明白了。但是我想在解析之前在同一个函数中处理所有令牌逻辑。有什么方法可以做到这一点吗?第一个代码片段等待
authHandler.onLogin()
但是没有
authHandler
,因此条件立即计算为false。您是想让
if(等待此.onLogin())
,也许?旁注:将拒绝/错误转换为带标志的履行/返回通常是一种反模式。在大多数情况下,调用代码应该知道检查授权的尝试失败,而不是返回负面结果。第二个代码段是旧版本,因为要存储客户端机密服务器端,我必须重新编写是的,很抱歉,我忽略了一个事实,这是在一个使用类和组件的react本机项目中,所以这里一切正常。如前所述,我确实得到了令牌,所有这些,函数只是很早就解决了。
axios.get
是异步的。但您不会等待它,也不会从
onLogin
返回任何内容>在您的第一个代码段中。您必须执行
返回axios.get(…
derpirscher.I明白了。但是我想在同一个函数b中处理我的所有令牌逻辑