首页 > 解决方案 > 在循环内进行重复的ajax调用,直到满足条件

问题描述

我正在调用一个实现了分页的 API。API 的响应是

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

请求中指定了分页键的值,分页键的响应值成为下一个请求的分页键。第一次请求时分页键的值为空,响应中分页键的最终值为空。所以本质上我必须用 null 的分页键值调用 API,然后我得到的任何分页键值作为响应,将它用于第二个请求并继续继续,直到响应中的键值变为 null。

我的问题是我正在使用 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 时打破这个循环。我怎样才能做到这一点?

标签: javascriptjqueryajax

解决方案


由于在发起新呼叫之前需要等待呼叫完成,您可以使用标准循环。一个简单的解决方案是在调用完成后调用 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)

如果你需要一个页面数组,你可以在一个循环中使用async/await 。for...of对于不是 的每个键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


推荐阅读