【问题标题】:Fetch API always returning a promiseFetch API 总是返回一个 Promise
【发布时间】:2020-12-06 05:48:17
【问题描述】:

我在调用 api 的地方有以下代码


    const fetchToken = async () => {
      const response = await axios.post("http://localhost:3000/api/getRedisData", 
      {
        key: process.env.AUTH_TOKEN_NAME!,
      });
      console.log(response); // this returns what I expect it to return
      return response;
    };

那我就这样调用函数了。


    fetchToken();

现在,这个功能可以正常工作了。但是当我尝试保存此响应的数据时,如下所示。


    token = fetchToken().then((r) => r);

它返回一个承诺,它永远不会解决。发生了什么,我该如何等到这个承诺解决。我只需要等待并获取数据。提前致谢。

我更新了这个问题。

假设我有以下对象。

    const authMachine = createMachine<toggleAuth>({
      id: "auth",
      initial: "unauthenticated", // I want to chage this value based on token
      context: {
        //
      },
      states: {
        //
      },
    });

现在我想根据我是否获得令牌来更新初始属性。现在我正在做这样的事情。

    initial: token ? "authenticated" : "unauthenticated"

那么这里出了什么问题?

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    如果您在 async 函数中,则只需 await 它即可获取数据。

    const token = await fetchToken();
    console.log(token);
    // do other stuff with token
    

    如果您不是,那么您需要在 then 方法中使用令牌做所有您想做的事情。这是因为您正在调用 async 方法,而无法 await 它。执行将继续。 then 函数是您的 async 方法成功完成时发生的回调。

    fetchToken().then(token => {
      console.log(token)
      // do other stuff with token
    });
    

    【讨论】:

    • 我不在异步函数中。现在有办法在数据获取完成之前不执行另一行代码。因为现在如果我保存该函数,它会首先返回一个承诺,我不希望这样。
    • 你不能,这就是为什么你必须把你想与数据一起使用的代码放在then函数中。如果不使用async 函数,则无法等待该数据完成后再继续
    【解决方案2】:

    所有async 函数都返回一个承诺。因此,您的 fetchToken() 函数将始终返回一个承诺。该承诺的解析值将是您从 fetchToken() 函数体返回的任何值。

    因此,fetchToken() 的调用者必须使用 await.then() 来获取解析后的值。 async/await 没有免费的午餐。它仍然是异步的。 await 在函数内部提供类似同步的行为,但不在函数外部。

    再解释一下。当fetchToken() 执行时,一旦遇到第一个await,它会立即暂停函数体的进一步执行,然后立即将未解决的承诺返回给调用者。然后调用者继续执行,调用者必须使用.then()await 来知道fetchToken() 的主体何时真正完成以及它的最终返回值是什么。

    然后,稍后,您在 fetchToken() 内部使用的 await 承诺将解析或拒绝,当 JS 解释器返回事件循环时,它将继续执行 @987654336 主体的其余部分@ 在await 之后。当它最终到达函数体的末尾或遇到return 语句时,它会解析先前返回的promise,并且使用await.then() 的调用者将收到通知它已完成并且将被赋予最终返回值作为该承诺的解决值。然后调用者可以处理该最终值并执行其操作。

    因此,您可能希望使用这样的方法来获取最终值或错误:

    fetchToken().then(token => {
        console.log(token);
        // use the token value here
    }).catch(err => {
        console.log(err);
    });
    // you cannot use the token value here
    

    如果对fetchToken() 的调用本身在async 函数内,那么它也可以使用await

    try {
        let token = await fetchToken();
        console.log(token);
        // use the token value here
    } catch(err) {
        console.log(err);
    }
    

    【讨论】:

    • 我不在异步函数中。现在有办法在数据获取完成之前不执行另一行代码。因为现在如果我保存该函数,它会首先返回一个承诺,我不希望这样。
    • @Pranta - 不,您不能阻止执行。您必须使用.then()await 才能从promise 中获取价值。这就是 Javascript 的工作原理。
    猜你喜欢
    • 2019-12-19
    • 2019-05-28
    • 2017-01-19
    • 2017-09-11
    • 2019-05-05
    • 1970-01-01
    相关资源
    最近更新 更多