[英]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.