首页 > 解决方案 > 努力使异步函数等待数据库响应

问题描述

预先感谢您抽出宝贵时间帮助我。

我正在尝试使用 MongoDB 后端登录用户,我调用一个进行 fetch 调用的异步函数,如果我收到 200 响应代码,则返回登录令牌。:

_initialize = async userAddress => {

    const token = await login(userAddress);
    console.log("TOKEN:", token);

    // Do other stuff with the token
  }

登录功能如下所示:

export const login = async address => {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ address })
      };
  
      let responseCode;
      fetch(`___ENDPOINT___`, requestOptions)
        .then(response => {
          responseCode = response.status;
          return(response.json());
        })
        .then(data => {
          if(responseCode == 200){
            console.log(data.token)
            const token = data.token;
            return token;
          }
          if(responseCode == 400){
            if(data.message === "User not yet registered"){
              // Do nothing
              return;
            }
          }
        })
        .catch(error => {
          console.log(error)
        });
}

我遇到的问题 await login()是没有等待呼叫,而是token控制台记录为undefined.

如果我删除await关键字,我会收到令牌:

Promise {<fulfilled>: undefined}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: undefined

我不明白,为什么令牌未定义?如果我在 .then 块中记录令牌,则它会成功返回,但这仅在令牌在initialize函数中打印为未定义后才会发生。

就像异步函数初始化不等待异步登录函数一样?

非常感谢您的帮助,再次感谢您的宝贵时间。

标签: javascriptreactjsmongodbasynchronous

解决方案


您的login函数不返回承诺。事实上,它根本不返回任何东西。看评论:

export const login = async address => {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ address })
    };

    // Note: Don't catch erros in this function, let them propagate
    // so the caller knows what happened
  
    // No need for `.then`/`.catch` in an `async` function, use `await`

    // Wait for the initial resaponse
    const response = await fetch(`___ENDPOINT___`, requestOptions);
    const responseCode = response.status;
    if (!response.ok) {
        // Not an OK reseponse
        if (responseCode == 400) {
            // Parse the body to see if we have the message
            const data = await response.json();
            if (data.message === "User not yet registered") {
                // Do nothing
                return;
            }
        }
        throw new Error("HTTP error " + responseCode);
    }

    // OK response, read the data from the body, this is also async
    const data = await response.json();
    return data.token;
};

请注意,如果响应代码为 400 并且该响应的主体是有效的 JSON 定义了text 的属性,login则将返回令牌将返回。将需要检查。此外,应该处理来自.undefinedmessage"User not yet registered"_initialize_initializelogin


推荐阅读