在平时开发中经常会遇到需要调用接口和外部服务的场景,但是有些接口服务方不能立即返回数据,而是需要处理一段时间才能返回真实的业务数据,如果没有处理完则直接返回一个中间状态的结果。
业务场景:
-
代码中存在依赖不稳定的场景,需要使用重试获取预期结果或者尝试重新执行逻辑不立即结束,比如远程接口访问,数据加载访问,数据上传校验等
-
对于异常需要重试的场景,同时希望把正常逻辑和重试逻辑解耦
-
对方接口不支持异步回调
接口返回的结果类似于{"errorCode":"-1", "errorMsg":"处理中", "result":""}
这样的结果,然后调用方需要过段时间(一般间隔几秒种后,需要根据具体的业务确认)再次调用才能获取真实的结果。
传统的写法如下(伪代码):
int time = 0;
do {
time++;
result = testRedo(); // 调用接口
} while (null == result && time < 5);
对于这种场景大家或多或少都遇到过,但上面这样的写法有几个很明显的弊端:
-
调用方需要不仅需要考虑多次调用的次数,还要考虑每次调用的间隔时间,尽量在最少调用情况下获取到最终结果(多一次请求意味着多一次网络开销,不方便实时调整)
-
多次调用过程中偶尔有一次调用出现异常(接口报错,网络异常),如果没有异常处理就会影响剩下次数的调用,无法保证高可用
-
多线程情况下上面的代码会出现并发问题,因为第一次调用的结果不一定是最早返回的,有可能后面调用的先返回,导致结果不是预期的
-
性能问题,如果使用多线程要考虑线程创建销毁和切换问题
当然这些问题自己实现完全可以解决,但已经有现成的轮子我们可以直接拿来用