如何在不返回promise或调用done回调的情况下解析异步mocha测试

时间:2017-07-17 07:28:14

标签: javascript promise async-await mocha

我希望更好地理解以下示例为什么按预期工作的内部结构:

describe('async await', () => {
    it('resolves without return', async () => {
        await asyncOperation();
    });
});

function asyncOperation() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, 123);
    });
}

通常,异步mocha测试必须返回一个promise(或执行完成的回调),但在此示例中没有返回任何内容,但mocha测试仍然有效。这究竟是如何工作的?

2 个答案:

答案 0 :(得分:6)

来自async documentation

  

async函数声明定义了一个异步函数,它返回一个AsyncFunction对象。

     

<强>描述

     

调用异步函数时,会返回Promise 。当异步函数返回一个值时,将使用返回的值解析Promise。当异步函数抛出异常或某个值时,将使用抛出的值拒绝Promise。

这意味着,在您的情况下,会返回Promise,这就是您的测试有效的原因。

答案 1 :(得分:1)

当您使用async关键字时,您隐式返回Promise实际使用的return函数的Promise语句中的Promise<void>(在这种情况下,您不返回任何事情,所以这只是async/await什么都没有,或await如果你是TypeScript)。

在内部,使用await的函数会展开到多个异步延续中,并在每次使用function asyncOperation() { return new Promise((resolve) => { setTimeout(() => { resolve(); }, 123); }); } async () => { await asyncOperation(); } 关键字时进行拆分。当您{4}}的承诺完成时,函数的其余部分将恢复。看看像Babel这样的转发器如何展开你的代码可能是有益的。

此代码:

"use strict";

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

function asyncOperation() {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve();
        }, 123);
    });
}

_asyncToGenerator(regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
            switch (_context.prev = _context.next) {
                case 0:
                    _context.next = 2;
                    return asyncOperation();

                case 2:
                case "end":
                    return _context.stop();
            }
        }
    }, _callee, undefined);
}));

被转换为简单的ES5:

_asyncToGenerator

那个丑陋的cursor:pointer调用曾经是你美丽的异步函数。它已经展开为显式延续(you can try为函数添加更多等待点和逻辑,并查看转换后的代码如何更改。)

相关问题