typescript 在 JS 中测试异步函数 - 错误:“您是否忘记使用等待”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54043275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:45:43  来源:igfitidea点击:

Test an Async function in JS - Error: "Did you forget to use await"

typescriptasync-awaitjestjses6-promise

提问by lanzchilz

My code looks like this:

我的代码如下所示:

public getUrl(url) {
//returns URL
 ... }

public getResponseFromURL(): container {
  let myStatus = 4;
  const abc = http.get(url, (respon) => 
  const { statusCode } = respon;
  myStatus = statusCode;
  console.log('Inside callback' +myStatus);
  .on('error', (err) => {
  console.log('Things have gone wrong' + err);
  });
  console.log('ITS COMPLICATED' +myStatus);
  return new Container(status, body, header);
  }
}

The problem I am facing is because of the asynchronous nature of JS and the console.log('ITS COMPLICATED') gets executed before the one in the callback function. I am trying to have the first one executed before the last console.log!

我面临的问题是因为 JS 的异步性质,并且 console.log('ITS COMPLICATED') 在回调函数中的那个之前被执行。我试图在最后一个 console.log 之前执行第一个!

I am using Async/Await like below:

我正在使用 Async/Await,如下所示:

  public timeoutPromise(time: any) {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(Date.now());
      }, time);
    });
  }

  public doSomethingAsync() {
    return this.timeoutPromise(1000);
  }

As a result changed my getResponseFromURL() to:

结果将我的 getResponseFromURL() 更改为:

public async getResponseFromURL(): Promise<container> {
    this.myStatus = 7;
    console.log(0);
    await this.doSomethingAsync();
    console.log(1);
    const abc = http.get(url, (respon) => {
      const { statusCode } = respon;
      this.myStatus = statusCode;
      console.log('Inside Callback ' + statusCode);
    }).on('error', (err) => {
      console.log('Things have gone wrong ' + err);
    });
    await this.doSomethingAsync();
    console.log(2);
    await this.doSomethingAsync();
    console.log('Is it simple lalala ' + this.myStatus);
    await this.doSomethingAsync();
   }
}

The problem with doing this was if my container class (return type of getResponseFromURL()) is a container for status and body when I am testing this async function, before expect.getResponseFromURL().getStatus().toBe(200)would work.

这样做的问题是,如果我的容器类(getResponseFromURL() 的返回类型)在我测试此异步函数时是状态和正文的容器,那么之前expect.getResponseFromURL().getStatus().toBe(200)会起作用。

Test looks like below:

测试如下所示:

  test('Async function', async () => {
    expect.assertions(1);
    const data = await ContainerGlobals.getResponseFromURL().getStatus();
    expect(data).toBe(207);
  });

Now I am getting error from .getStatus()and I am not sure how to bypass this error?

现在我收到错误.getStatus(),我不知道如何绕过这个错误?

"does not exist on Promise"

“不存在于 Promise”

回答by Brian Adams

In the code above awaitis called on the result of calling getStatuson the result of calling ContainerGlobals.getResponseFromURL().

在上面的代码await中调用结果调用调用getStatus的结果ContainerGlobals.getResponseFromURL()

ContainerGlobals.getResponseFromURL()returns a Promiseand immediately calling getStatus()on the Promisegives an error since getStatus"does not exist on Promise".

ContainerGlobals.getResponseFromURL()返回Promise并立即调用getStatus()Promise给出了因为一个错误getStatus“不存在的Promise”。

awaitneeds to be called on the Promisereturned by ContainerGlobals.getResponseFromURL(), and getStatusshould be called on the result returned by await.

await需要在Promise返回的上调用ContainerGlobals.getResponseFromURL(),并且getStatus应该在 返回的结果上调用await

The quickest way to fix this is to throw parenthesis around the await:

解决这个问题的最快方法是在 周围加上括号await

test('Async function', async () => {
  expect.assertions(1);
  const data = (await ContainerGlobals.getResponseFromURL()).getStatus();
  expect(data).toBe(207);  // SUCCESS
});

...but you might want to split the awaitline into two lines for readability:

...但您可能希望将该await行分成两行以提高可读性:

test('Async function', async () => {
  expect.assertions(1);
  const result = await ContainerGlobals.getResponseFromURL();  // let the Promise resolve
  const data = result.getStatus();  // call getStatus on the result
  expect(data).toBe(207);  // SUCCESS
});