使用Promise实现重复请求接口,直到返回success状态为止

125 阅读2分钟

在Vue中,可以使用递归函数和Promise实现重复请求接口,直到返回success状态为止,以下是一个简单的示例代码:

function callApi(retryCount = 0) {
  return new Promise((resolve, reject) => {
    if (retryCount >= 10) return reject(Error('API请求次数过多'));

    axios.get('/your-api-url')
      .then((response) => {
        const data = response.data;
        if (data.status === 'success') {
          resolve(data); // 如果状态为success,返回数据
        } else if (data.status === 'running') { // 如果状态为running,再次递归调用函数
          setTimeout(() => {
            callApi(retryCount + 1)
              .then(resolve)  // 注意使用 then(resolve) 回调,等待第二次请求成功后,resolve数据
              .catch(reject); // 在递归调用后,将reject传递给层promise
          }, 1000);
        } else {
          reject(Error('API返回状态异常')); // 如果状态既不是running,也不是success,返回异常信息
        }
      })
      .catch(error => {
        reject(error); // 如果请求失败,返回异常信息
      });
  });
}

callApi().then((data) => {
  console.log(data);
}).catch((error) => {
  console.error(error);
});

以上代码中,我们定义了一个名为callApi()的递归函数,该函数通过axios库请求API,并检查API响应状态。如果API响状态为"success",返回API数据,否则如果响应状态为"running",重复调用callApi()函数,直到API响应状态为"success"。如果API响应状态既不是"running"也不是"success",返回一个异常。在主Vue组件中,我们调用callApi()函数,然后处理Promise返回的数据。

thencatch方法中,返回的是一个新的Promise对象。当一个Promise被resolve时,它所对应的then方法会被执行,同时它也返回了一个新的Promise,新的Promise会resolve这个.then方法的返回值。同样的道理,当一个Promise被reject时,它所对应的catch方法会被执行,同时它也返回了一个新的Promise,新的Promise会resolve这个.catch方法的返回值。

在代码中,then(resolve)表明将Promise的resolve传递给下一层,以返回异步获取到的API数据。catch(reject)也是同样道理,表明将Promise的reject方法传递给下一层,以处理API响应错误。这两个操作都是Promise在链式调用中,将下一级结果通过解析当前级别的返回值(即上一级返回的状态/值/函数)并转发流程到下一层级。

需要注意的是,then catch方法的返回值实际上是一个新的Promise对象,所以可以链式调用不同方法,直到最后一个.then()或或 .catch()处为止。