即使测试没有 return 承诺,qunit 如何知道异步测试回调何时完成?

How does the qunit knows when the async test callback is complete even though the tests does not return promise?

Qunit 一个接一个地执行异步测试,但是它怎么知道测试已经完成,因为测试没有 return qunit 可以等待的 Promise?

在此演示示例中 https://jsfiddle.net/6bnLmyof/

function squareAfter1Second(x) {
    const timeout = x * 1000;
    console.log("squareAfter1Second x:", x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(x * x);
        }, timeout);
    });
}

const { test } = QUnit;

test( "an async test", async t => {
    console.log("starting test1");
    t.equal( await squareAfter1Second(3), 9 );
    t.equal( await squareAfter1Second(4), 16 );
});

test( "an async test2", async t => {
    console.log("starting test2");
    t.equal( await squareAfter1Second(1), 1 );
});

有 2 个异步测试 运行 一一进行。测试 post 事件循环的宏任务 (setTimeout),但不知何故 qunit 能够等待测试完成,尽管测试没有 returning 承诺。此外,在 qunit 的源代码中没有 await 关键字。

这就是 await 的重点(异步等待 promise 结果,然后才继续)

Async 函数总是 return Promise,一旦到达其块的末尾(或到达 return)就会解决。因此,即使没有显式 returned,awaits 意味着两个异步回调都隐含地 return 在函数中的所有 awaits 完成后解析的承诺。所以 test 只需要遍历调用它的每个回调函数,并且 await 每次调用。

下面是一个您也可以自己实现的示例,无需更改 squareAfter1Secondtest 调用中的任何代码:

const queue = []
const test = (_, callback) => {
  queue.push(callback);
};

function squareAfter1Second(x) {
    const timeout = x * 1000;
    console.log("squareAfter1Second x:", x);
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(x * x);
        }, timeout);
    });
}

test( "an async test", async t => {
    console.log("starting test1");
    t.equal( await squareAfter1Second(3), 9 );
    t.equal( await squareAfter1Second(4), 16 );
});

test( "an async test2", async t => {
    console.log("starting test2");
    t.equal( await squareAfter1Second(1), 1 );
});

(async () => {
  for (const callback of queue) {
    console.log('Awaiting callback...');
    await callback({ equal: () => void 0 });
    console.log('Callback done');
  }
})();