异步/等待不等待响应,返回Promise对象

3
使用ES6、类和异步/等待,我们的目标是创建一个“Api”类,使用fetch进行异步调用并返回一些数据……但即使是基础框架也无法正常工作。在主JavaScript文件中,以下代码片段将启动事件链:
let api = new Api();
let api_data = api.getLocation();

console.log(api_data);

getLocation 方法如下,它会返回一些响应/数据。然而,那些数据理论上是对 API 的 "getTestVariable" 发起的 fetch 调用,例如它需要等待一段时间...

class Api {
  getLocation = async () => {
    var response = await this.getTestVariale();
    console.log(response);
    return response;
  }


  getTestVariale = () =>{
    setTimeout(function(){
      console.log("timeout done...");
      return "this is the test variable";
    },2000);
  }
 }

然而,1. 当没有等待时 console.log(response) 返回 "undefined"... 2. 回到主 js 中,当打印 api_data 时,是一些 Promise 对象而不是变量 response


2
嗨!按设计,Await不会等待setTimeout函数。 Await可以等待任何将返回Promise对象的函数。 阅读此文章以获取更多信息 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function - Drag13
1
@Drag13即使我完全删除setTimeout,并且只是返回原样的字符串,然后api_data被记录为一个Promise。我如何将response的实际值作为变量获取? - user10265865
1
你需要使用特殊对象 - Promise。如果你想返回字符串,你需要用 Promise 包装它。请查看下面的示例。但最好先了解一下 Promise 的概念,然后再转向异步解决方案。 - Drag13
1
正如@Drag13所说。我的示例为您提供了即时解决方案,但您可能需要花些时间阅读有关JavaScript中Promise及其处理方式的内容。 - Peter Van Drunen
1
并返回Promise对象” - 这是预期的。执行异步操作的API不能立即返回数据,它只能返回一个Promise。 async/await语法并不使任何东西同步,它只是使处理Promise变得更加容易。 - Bergi
显示剩余2条评论
2个回答

0
如上面的评论所述,setTimeout不返回Promise,因此getTestVariable没有返回值。
这是您代码的稍微修改版本,希望能让您走上正确的轨道:
class Api {
  getLocation = async () => {
    var response = await this.getTestVariale();
    console.log(response);
    return response;
  }


  getTestVariale = () => {
      return new Promise((resolve, reject) => {
          if (thereIsError)
              reject(Error('Error message'));
          else 
              resolve({foo: 'bar'});
      }
  }
}

如果需要进一步解释,请留言,我很乐意帮助。

0
getLocation 中,你需要 await 一个值,这个值将会来自于 this.getTestVariable。为了让它工作,this.getTestVariable 必须返回一个 Promise;有两种方法可以实现 - 将 getTestVariable 变成一个 async 函数或者显式地返回一个 Promise。
由于你正在使用 setTimeout(它不是一个 async 函数),所以你必须使用 Promise。下面是代码示例:
class Api {
  async getLocation() {
    return await this.getTestVariable();
  }

  getTestVariable() {
    return new Promise((res, rej) => {
      setTimeout(() => res('test'), 2000)
    });
  }
}

async function main() {
  let api = new Api;

  console.log('Trying to get the location...');
  console.log('Voila, here it is: ', await api.getLocation());
}

main();

看起来很丑,但如果使用set timeout,你就无法实现它。

关键在于解决getTestVariable的分辨率,以及所需返回的值。

非常重要的一点是:你可以将getTestVariable标记为async函数,这将添加一个额外的Promise级别,但你仍将获得所需的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接