在我正在构建的应用程序中,有一个用例,我需要引发第一个 API 调用,等待响应,然后使用响应中的信息引发第二个 API 调用。像这样:
firstAPI.call(some input)
.then(firstResponse => {
return secondAPI.call(firstResponse);
})
.then((secondResponse) => {
//do something
})
.catch(error => {
console.error(error);
});
这些都工作正常。但是,目前由于某种原因,第二个 API 调用不能在第一个 API 调用之后立即引发,并且必须有一些间隔才能工作。然后我尝试使用这样的.setTimeout()
:
firstAPI.call(some input)
.then(firstResponse => {
//save the response somewhere
})
.then(() => {
// Wait 1.5s before calling the second API
return this.sleep(1500);
})
.then(() => {
return secondAPI.call(saved first response);
})
.then((secondResponse) => {
//do something
})
.catch(error => {
console.error(error);
});
private sleep(milliseconds: number): Promise<Object> {
return new Promise(resolve => {
setTimeout(resolve, milliseconds)
});
}
我针对以下场景测试了此代码片段:
1(第一次和第二次通话都成功 - 工作正常,睡眠时间为1.5秒;
2(第一次调用失败 - 工作正常,捕获错误;
3(第一次调用成功,但第二次调用失败 -不起作用;错误未捕获!单元测试代码段如下:
describe('when first call succeeds but second call fails', () => {
it('should log errorMsg', fakeAsync(() => {
let mockFirstResponse: Promise<Object> = Promise.resolve(some mock response);
spyOn(firstAPI, 'call').and.returnValue(mockFirstResponse);
spyOn(secondAPI, 'call').and.returnValue(Promise.reject(new Error('Oops!')));
spyOn(console, 'error').and.callThrough();
underTest.submit(); // Call my function
tick(1500);
expect(console.error).toHaveBeenCalled();
}));
});
单元测试失败,出现错误:
错误:未捕获(承诺(:错误:糟糕! at resolvePromise (webpack:///~/zone.js/dist/zone.js:469:0 <- configuration/karma/karma-entry.js:128867( at webpack:///~/zone.js/dist/zone.js:528:0 <- configuration/karma/karma-entry.js:128926
.catch
块根本没有执行。
我的假设是,.setTimeout()
以某种方式打破了链条。执行此操作的首选方法是什么?
我很欣赏你的代码正在做一些非常相似的事情,但要
试一试。向链引入一个新的承诺,它只做任何事情,只是延迟链中下一个区块的执行,如下所示:
firstAPI.call(someinput)
.then(firstResponse => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(firstResponse);
}, 1500)
})
})
.then(firstResponse => {
return secondAPI.call(firstResponse);
})
.then((secondResponse) => {
// do something
})
.catch(error => {
console.error(error);
});
根据总的猜测,需要延迟的原因可能是由于服务器在响应后执行一些需要一两秒才能完成的处理,或者它可能重新索引或一些抖动扑克。