Повторяйте вызовы ajax внутри цикла, пока не будет выполнено - PullRequest
0 голосов
/ 10 ноября 2018

Я звоню API, в котором реализована нумерация страниц. Ответ от API:

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

Значение ключа нумерации страниц указывается в запросе, а значение ответа для ключа нумерации страниц становится ключом нумерации страниц для следующего запроса. Значение для ключа нумерации страниц будет нулевым для первого запроса, а окончательное значение ключа нумерации страниц в ответе будет нулевым. Поэтому, по сути, я должен вызвать API со значением ключа нумерации страниц, равным нулю, затем любое значение ключа нумерации страниц, которое я получу в ответе, использовать его для второго запроса и продолжать до тех пор, пока значение ключа в ответе не станет нулевым.

Моя проблема в том, что я выполняю ajax-вызов с использованием JQuery для этого API, например

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 и failCallBack - методами, которые я определил

Теперь вызов Ajax и последующие обратные вызовы, являющиеся асинхронными в JS, затрудняют выполнение этих запросов в цикле и выход из этого цикла, когда paginationKey ответа становится нулевым. Как мне этого добиться?

1 Ответ

0 голосов
/ 10 ноября 2018

Поскольку вам нужно дождаться завершения вызова, прежде чем начинать новый вызов, вы можете использовать стандартный цикл. Простое решение состоит в том, чтобы вызвать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...