在循环内重复进行ajax调用,直到满足条件

时间:2018-11-10 15:35:31

标签: javascript jquery ajax

我正在调用已实现分页的API。 API的响应是

{
  data {
    field1 : "value1",
    field2: "value2",
  },
  paginationKey : {
    id: "value for id",
    some_other_field: "value for other field"
  }
}

在请求中指定了分页键的值,并且分页键的响应值成为下一个请求的分页键。 对于第一个请求,分页键的值将为null,响应中的分页键的最终值将为null。因此,从本质上讲,我必须使用分页键值为null的API进行调用,然后无论响应中得到的分页键值如何,都将其用于第二个请求,并继续进行直到响应中键的值变为空。

我的问题是我正在使用JQuery对这个API进行ajax调用

let ajaxPromise = $.ajax({
  url: requestUrl,
  type: 'GET',
  data: requestData, // containing the paginationKey like I mentioned above
  // other parameters for AJAX call like crossdomain, timeout etc
})

ajaxPromise.then(function(data) {
  successCallBack(data);
}, function(error, errorMessage) {
  failureCallBack(error, errorMessage)
})

successCallBack和failureCallBack是我定义的方法

现在进行Ajax调用,并且随后的回调在JS中是异步的,我很难在一个循环中发出这些请求,并且当响应paginationKey变为null时,很难退出该循环。 我该如何实现?

1 个答案:

答案 0 :(得分:0)

由于在启动新呼叫之前需要等待呼叫结束,因此可以使用标准循环。一种简单的解决方案是在调用完成后调用API,并且密钥不是null

const repeatedAPICall = (requestData, successCallBack, failureCallBack) => {
  const ajaxPromise = $.ajax({
    url: requestUrl,
    type: 'GET',
    data: requestData, // containing the paginationKey like I mentioned above
    // other parameters for AJAX call like crossdomain, timeout etc
  })

  ajaxPromise.then((data) => {
    successCallBack(data)

    if(data.paginationKey) {
      repeatedAPICall(data.paginationKey, successCallBack, failureCallBack)
    }
  }, (error, errorMessage) => {
    failureCallBack(error, errorMessage)
  })
}

// 1st call
repeatedAPICall(null, successCallBack, failureCallBack)

如果需要页面数组,可以在for...of循环中使用async/await。对于不是null的每个键,我们将键添加到数组中。如果数组中有键,我们将进行api调用,并将结果添加到results数组中。

async function repeatedAPICall(
  apiCall,
  startValue
) {
  const keys = [startValue];
  const result = [];

  for (const callKey of keys) {
    const data = await apiCall(callKey);

    result.push(data);

    if (data.key !== null) keys.push(data.key);
  }

  return result;
}

// mock api call
const apiCall = ((counter) => () => Promise.resolve({
  key: counter < 5 ? counter++ : null
}))(0);

repeatedAPICall(apiCall, null)
  .then(result => console.log(result)); // use your callbacks here