编写omniPoller模拟接口请求逻辑

今天看到简书上一个动态,有道题挺感兴趣的,我把原来的链接发出来:
请实现一个功能’ omniPoller ', 用来模拟真实的轮询

我把要求列出来:

  • omniPoller函数接受两个参数:queryStatussuccessCallback
  • queryStatus是一个返回truefalse的函数
  • successCallback是一个函数,应该在queryStatus返回true时调用。
  • omniPoller应该定期调用queryStatus
    • 当调用一把queryStatus即成功时,即一次就返回true,则直接执行成功回调
    • queryStatus返回false时,它会等待一段时间并再次调用queryStatus,直到queryStatus返回true
    • 第一次失败后,于1秒后重新调用queryStatus函数,如再失败,往后均为1.5s后再次调取
    • queryStatus返回true时,调用successCallback并退出函数

例如:

  • 初次直接请求接口,正常请求,如成功直接退出,如失败,则按照下面步骤:
  • 第一次失败: 1秒后,调用’ queryStatus ‘,返回’ false ’
  • 第二次失败: 再过1.5秒后,调用’ queryStatus ‘,返回’ false ’
  • 第三次失败: 再过1.5秒后,调用’ queryStatus ‘,它返回’ false ’
  • 第四次失败: 再过1.5秒后,调用’ queryStatus ‘,返回’ true ‘,执行’ successCallback ',退出

首先看一下原作者代码:

var num = 1;
function omniPoller(queryStatus,Callback){
  let timer = 1000;
  let cleartime = setInterval(() => {
    if(num!=1){
      timer = timer*1.5;
    }
    console.log(timer)
    let status = queryStatus();
    if(status){
    Callback();
    clearInterval(cleartime)
  }
  }, timer);
}
function queryStatus(){
  num+=1;
  return num==5?true:false;
}
function successCallback(){
  console.log("成功")
}
omniPoller(queryStatus,successCallback);

原作者的问题有如下几个问题:

  • cleartime中的numtimer的获取和设置由于是同步的,设置的时候你会发现,timer永远都是1000就打印了
  • queryStatus去模拟查询结果,其实用parseInt(Math.random() * 2)更好
  • 如果用户一把就获取成功拿到值的话,是不需要设置定时器的,所以你这写法没有处理好一次就获取成功的可能性

为了真实的模拟接口的真实性,咱们用js中Mathrandom方法来模拟接口随机返回truefalse,同时用ES6中的asyncawait方法来模拟同步操作,我把修改后的逻辑修改如下:

/**
 * omniPoller模拟接口请求逻辑
 * 当接口返回true时则执行成功回调,
 * 当接口请求失败时,第一次后等1秒重新请求,接口返回true时则执行成功回调,如若再次失败则以后每次等5000秒后重新请求,直至成功
 */
 
var num = 1;

async function omniPoller(queryStatus, successCallback) {
  await queryStatus().then((data) => {
    successCallback(data);
  }).catch( err => {
      setTimeout(() => {
        omniPoller(queryStatus, successCallback);
      },num == 2 ? 1000 : 5000)
  })
}

function queryStatus() {
    return new Promise((reslove,reject) => {
      let status = parseInt(Math.random() * 2);
      if (status != 1) {
        console.log(`第${num}次请求失败,需要发送第${num + 1}次请求`);
        ++num;
        reject('01');
      } else {
        console.log(`第${num}次请求成功`);
        reslove('00');
      }
    })
}

function successCallback(data) {
  console.log(data)
}

omniPoller(queryStatus, successCallback);

运行结果如下:

浏览器运行结果

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值