简体   繁体   English

为什么使用.then()的速度快3倍,然后等待测试?

[英]why is using .then() 3x faster then await in my test?

This could totally be me misunderstanding something about the way async/await works in Javascript, but I haven't figured it out yet. 这可能完全是我误解了Java中异步/等待的工作方式,但是我还没有弄清楚。

I have a simple test that uses some helpers to generate mock data before actually running the test. 我有一个简单的测试,该测试在实际运行测试之前使用一些助手来生成模拟数据。

Here's the helper function: 这是辅助函数:

async create(numCustomers, businessId, options) {

    options = _.assign({ type: 'customer' }, options);

    const customers = await Factory.createMany('user', options, numCustomers);

    return Promise.all(customers.map(async (c) => {
        await AccountHelper.create(businessId, c.get('id'));
        return c;
    }));
}

and here's two versions of the test: 这是测试的两个版本:

async/await version: async/await版本:

const customers = await CustomerHelper.create(10, Constants.fakeBusinessId);

await Promise.all(customers.map(async (c) => {
    await PetHelper.create(1, c.get('id'));
}));

const res = await server.inject(request);
expect(res.statusCode).to.equal(200);

.then() version: .then()版本:

CustomerHelper.create(10, Constants.fakeBusinessId).then(async (customers) => {

    await Promise.all(customers.map(async (c) => {
        await PetHelper.create(1, c.get('id'));
    }));

    const res = await server.inject(request);
    expect(res.statusCode).to.equal(200);
});

The .then() version finishes in about 2 seconds, where the async/await version finishes in almost 7 seconds. .then()版本在大约2秒内完成,而async/await版本在大约7秒内完成。 Changing between these two forms seems to be the only variable. 在这两种形式之间进行更改似乎是唯一的变量。

I'm running Node 8.9.4 on OSX. 我在OSX上运行Node 8.9.4。

I appreciate any insights or education :) 我感谢任何见解或教育:)

Both methods should be roughly the same duration, as long as you are properly signaling your test framework that the test is done . 只要您正确地向测试框架发出测试已完成的信号 ,这两种方法的持续时间就应该大致相同。 (Either by returning a promise or calling the done callback, in most test frameworks) (在大多数测试框架中,通过返回Promise或调用done回调)

If you do not signal the framework properly, then the test will exit before the async processing is finished (or even started, in many cases). 如果您没有正确指示框架,则在异步处理完成(在许多情况下甚至开始)之前,测试将退出。 Also, if your assertions / expectations wait for an asynchronous event, then they will not even be made, and a test with no assertions is (in most frameworks) a passing test. 同样,如果您的断言/期望等待异步事件,那么它们甚至不会被创建,并且没有断言的测试(在大多数框架中)是通过测试。 Because of this, async / await is becoming the preferred style for tests, because it is harder (though not impossible) to incorrectly signal the test framework (as your example illustrates). 因此, async / await已成为测试的首选样式,因为不正确(尽管并非不可能)错误地向测试框架发出信号(如您的示例所示)。

Proper ways to signal a test framework the test is done (for mocha/jest style frameworks): 正确表示测试框架已完成的信号(对于mocha / jest样式框架):

it('does async work with await', async function (){
  let result = await asyncWork()
  assertItWorked(result)
})

it('does async work with returned promise', function (){
  return asyncWork().then(function (result) {
    assertItWorked(result)
  })
})

it('does async work with promise and callback', function (done){
  asyncWork().then(function (result) {
    assertItWorked(result)
    done() // note that this method will timeout if it fails, instead of displaying the error message, but you still get a failure
  })
})

it('does async work with promise and chained callback', function (done){
  asyncWork().then(function (result) {
    assertItWorked(result)
  }).then(done)
})

Improper ways that almost look right: 看似正确的不正确方法:

it('does async work but does not wait', function (done){
  asyncWork().then(function (result) {
    assertItWorked(result)
  })
  done() // this gets called before async work is done, and no assertions are made
})

it('does async work with promise and chained callback, but calls callback too soon', function (done){
  asyncWork().then(function (result) {
    assertItWorked(result)
  }).then(done()) // this is effectively identical to the previous example, because done gets called immediately
})

also note that the async / await style fully catches thrown errors/rejections from asyncWork , although with more code the other styles could as well. 还应注意, async / await样式可以完全捕获asyncWork引发的错误/拒绝,尽管使用更多代码,其他样式也可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么将Nightmarejs与async / await一起使用时,我的诺言为何无法解决? - Why is my promise not resolving when using async/await with nightmarejs? 为什么使用 await 也会在我的代码中给出一个未决的 promise ? - Why using await is also giving a pending promise in my code? jQuery animate()重复3次 - jQuery animate() repeats 3x 为什么 no-return-await vs const x = await? - Why no-return-await vs const x = await? 为什么添加立即调用的 lambda 会使我的 JavaScript 代码快 2 倍? - Why does adding in an immediately invoked lambda make my JavaScript code 2x faster? 为什么我在Jasmine 1.3.x中的AngularJS异步测试无法正常工作? - Why my AngularJS async test in Jasmine 1.3.x is not working? 当对我的 firebase auth mock 进行多次调用时,为什么在我的 vue.js 单元测试中需要额外等待? - Why is an extra await required in my vue.js unit test when more than one call is made to my firebase auth mock? ReferenceError: X 未定义(使用异步/等待) - ReferenceError: X is not defined (using async/await) 如何使用 await 使用 mocha 测试异步代码 - How to test async code with mocha using await 为什么我的async / await函数异常?(Javascript) - Why my async/await function is abnormal?(Javascript)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM