#javascript #async-await #coffeescript #mocha.js #es6-promise
#javascript #async-await #coffeescript #mocha.js #es6-обещание
Вопрос:
Итак, у меня есть такой тест:
it 'sample test', (done)->
await Promise.resolve 0
Promise.resolve 0
.then ->
done()
null
Обратите внимание, что null
в конце концов, чтобы избежать возврата Promise.
Однако тест падает с классическим "Error: Resolution method is overspecified. Specify a callback *or* return a Promise; not both"
Я проверил результат JS-кода, ничего странного:
it('Sample test', async function(done) {
await Promise.resolve(0);
Promise.resolve(0).then(function() {
return done();
});
return null;
});
Я не понимаю, что не так, потому что (как я думаю) этот код не должен возвращать обещание.
Кроме того, когда я завернул первое обещание (с await
помощью) в setTimeout
, оно работает нормально.
it 'working test', (done)->
setTimeout ->
await Promise.resolve 0
, 0
Promise.resolve 0
.then ->
done()
null
Конечно, с setImmediate
вместо setTimeout
этого тоже работает, поэтому я думаю, что лекарство в этой ситуации — обратный вызов. Но это чрезвычайно грязное решение.
Как более четко смешать then
, async-await
и done
в одном тесте?
Ответ №1:
Использование await
в теле функции превращает тестовую функцию в async
функцию.
async
функции всегда возвращают Promise
.
Итак, в этом случае:
it('Sample test', async function(done) {
await Promise.resolve(0);
Promise.resolve(0).then(function() {
return done();
});
return null;
});
…тестовая функция возвращает a, Promise
который разрешит null
.
В вашем другом примере Mocha не жалуется, потому что код компилируется в этот:
it('working test', function(done) {
setTimeout(async function() {
return (await Promise.resolve(0));
}, 0);
Promise.resolve(0).then(function() {
return done();
});
return null;
});
…поскольку await
теперь находится в теле функции, переданной setTimeout
.
(Обратите внимание, что два теста ведут себя очень по-разному).
Нет причин использовать обе done
и async / await
тестовую функцию (или ту, которая возвращает Promise
), поэтому Mocha завершает тест с этой ошибкой.
Ваш первый тест может быть упрощен до этого:
it 'sample test', ()->
await Promise.resolve 0
await Promise.resolve 0
… или, если вам нужно выполнить работу в then
привязке ко второму Promise
, вы можете просто сделать это:
it 'sample test', ()->
await Promise.resolve 0
await Promise.resolve 0
.then ->
// do stuff here
Ответ №2:
В Mocha версии v3.0.0 и новее возврат обещания и вызов done()
приведут к исключению, поскольку это обычно ошибка — документы
Поскольку async function
всегда возвращается Promise
, вы получаете эту ошибку. Возможные решения:
-
Удалить
async function
it('Sample test', function(done) { Promise.resolve(0) .then(function() { ... }) .then(function() { ... // if necessary }) .then(function() { done(); }); });
-
Возврат
Promise
it('Sample test', function() { return Promise.resolve(0) .then(function() { ... }) .then(function() { ... // if necessary }); });
-
Использовать
async/await
it('Sample test', async function() { await Promise.resolve(0); await Promise.resolve(0); });