开玩笑的文档说:
未解决的承诺
如果承诺根本无法解决,则可能会引发以下错误:
(等等)
就我而言,这不会发生。
我有这个测试:
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/