开玩笑的文档说:


  未解决的承诺
  
  如果承诺根本无法解决,则可能会引发以下错误:


(等等)

就我而言,这不会发生。
我有这个测试:

test('detect infinite loop', () => {
    expect.assertions(1);

    const vastPromise = VastUtils.parseFromUrl(infiniteLoopUrl);
    const expectedError =
        new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
   return expect(vastPromise).rejects.toEqual(expectedError);
});


VastUtils只需获取位于infiniteLoopUrl的XML,然后对其进行解析,如果该xml指向另一个xml,则VastUtils跟随链接,解析新的xml,合并它们并重复该过程。
现在,infiniteLoopUrl指向引用自身的XML,因此这是一个无限循环。
“正确”,代码将无限地跟随xml链接,并且永远不会解析或拒绝承诺。

我希望上述测试在一定的超时后会失败,但事实并非如此。

有人可以帮我吗?
谢谢



编辑:
我正在尝试用一个较小的示例重现一个无限的Promise循环,这是我注意到的:

此测试在5s后正确失败:

test('Promise2', () => {
    const genPromise = (): Promise<void> => {
        return new Promise((res) => {
            setTimeout(() => {
                res();
            }, 200);
        })
        .then(() => {
            return genPromise();
        });
    };

    const vastPromise = genPromise();

    const expectedError =
        new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
    return expect(vastPromise).rejects.toEqual(expectedError);
});


该测试在5s后不会失败(保持无限循环状态)

test('Promise', () => {
    const genPromise = (prom: Promise<void>): Promise<void> => {
        return prom
        .then(() => {
            return genPromise(Promise.resolve());
        });
    };

    const vastPromise = genPromise(Promise.resolve());

    const expectedError =
        new VastError(VastErrorCodes.WRAPPER_LIMIT_REACHED);
    return expect(vastPromise).rejects.toEqual(expectedError);
});


显然这些是相似的,但是我不明白造成玩笑无限循环的区别...

最佳答案

好的,我已经了解了问题所在。

原因是js的单线程性质。
在编辑部分的两个示例中,第一个示例有一个超时,因此有一段时间您可以控制并检查超时。
在第二个中不,所以开玩笑永远不要检查超时。

在我的真实情况下,问题出在假服务器上:它创建为:

server = sinon.fakeServer.create({
    respondImmediately: true
});


立即使sinon同步响应,以免开玩笑。
创建为:

server = sinon.fakeServer.create({
    autoRespond: true
});


sinon在10毫秒后做出响应,开玩笑可以检查经过的时间

关于testing - 开玩笑 Unresolved promise 不会失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52512949/

10-10 20:35