Как настроить переменную на основе результата выборки - PullRequest
0 голосов
/ 11 июля 2019

Я работаю над сценарием, который будет извлекать посты из разбитого на страницы API REST, предоставленного веб-сайтом, управляемым WordPress.

Я понял, что WordPress REST API разбит на страницы и получил ограничение в 100 объектов назапрос.

В приведенном ниже коде я пытаюсь получать посты постранично и по 20 постов на страницу.В конце я объединяю все извлеченные объекты в один большой объект.

Моя проблема в том, что при получении ответа HTTP 404 происходит сбой выборки, поскольку последний запрос содержит менее 20 сообщений.

Я хотел бы настроить переменную с именем limitPerPage, если выборка возвращается с 404 и уменьшать переменную, пока я не получу HTTP-ответ 200.

Моя проблема в том, что у меня не было опыта работы с обещанием получения.

Пожалуйста, посмотрите мой текущий скрипт ниже:


console.log('REST API is this: ' + apiUrl);

const getPosts = async function(pageNo = 1) {

    let limitPerPage  = 20;

    let requestUrl = apiUrl + `?page=${pageNo}&per_page=${limitPerPage}`;

    let apiResults = await fetch(requestUrl)
        .then(function(response){
            return response.json();
        })
        .catch(function(error){
            console.log(error.status);
        });

    return apiResults;

}

const getEntirePostList = async function(pageNo = 1) {

    const results = await getPosts(pageNo);

    console.log('Retreiving data from API for page : ' + pageNo);

    if (results.length > 0) {
        return results.concat(await getEntirePostList(pageNo+1));
    } else {
        return results;
    }

    };( async () => {

        const entireList = await getEntirePostList();
        console.log(entireList);
    })
();

Я ожидаю, что код уменьшит переменную 'limitPerPage 'на 1, если выборка возвращает ответ HTTP 404.

Нет необходимости просить окончательного решения моей проблемы.Я был бы признателен, если бы я предложил другой способ структурирования своего кода, чтобы получить нужный мне результат.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 11 июля 2019

Я думаю, что следующий код должен работать.Всегда используйте блок try ... catch внутри асинхронных функций

let entireList = [];
let finishEvent = new Event('finished');

document.addEventListener('finished', function (e) { 
  console.log(entireList);
}, false);

const getPosts = function (pageNo = 1) {

  let limitPerPage = 20;
  let requestUrl = `${apiUrl}?page=${pageNo}&per_page=${limitPerPage}`;

  return fetch(requestUrl)
    .then(function (response) {
      return response.json();
    })
    .catch(function (error) {
      console.log(error.status);
      return false;
    });

}

const getEntirePostList = async function (pageNo = 1) {
  try {
    const results = await getPosts(pageNo);

    console.log('Retreiving data from API for page : ' + pageNo);

    if (results && (results.length > 0)) {
      entireList.concat(results);
      getEntirePostList(pageNo + 1);
    } else {
      document.dispatchEvent(finishEvent);
    }

    return;
  } catch(e) {
    console.log(e)
  }
}; 

getEntirePostList();
0 голосов
/ 20 июля 2019

Мне удалось решить проблему самостоятельно с помощью приведенных выше предложений.Найдите решение здесь:

    // Constant variable with the assigned value of a joined string containing the base URL structure of the REST API request. 
const apiUrl = websiteUrl + '/wp-json/wp/v2/punkt/';

// Logging out the base URL of the REST API.
console.log('REST API is this: ' + apiUrl);

// Local variable with the default value of true assigned. Variable is used to control the paginated fetch of the API.
let keepfetchingPosts = true; 

// Local variable that contains the limit of posts per request. 
let limitPerPage  = 20;

// Constant variable, which is assigned a function as the value. The function is async and will return a promise. 
// The function takes one argument. The argument holds the value of the page number. 
const getPosts = async function(pageNo = 1) {

// Local variable assigned with the base URL string of the REST API request. Additional queries are added to the end of the string.
let requestUrl = apiUrl + `?page=${pageNo}&per_page=${limitPerPage}`;

// Logging out the REST API request
console.log('URL is this: ' + requestUrl); 

// Logging out the argument 'pageNo'
console.log('Retreiving data from API for page : ' + pageNo);

// Local variable assigned with a fetch function that returns a promise. The URL request are used as the function argument.  
let apiResults = await fetch(requestUrl)

    // If request is success, then log and return the following to the local variable.
    .then(function(response){

        // Logging out the status code of the response.
        console.log('HTTP response is: ' + response.status);

        // return JSON and status code of the XHR request
        return { 
            data: response.json(),
            status: response.status
        }

    })
    // Catch the error and log it out within the console. 
    .catch(function(error){

        console.log('HTTP response is: ' + error.status)

    });


// If the length of the request is less than the limitPerPage variable and status code is 200, then...
if (apiResults.length < limitPerPage && apiResults.status === 200){

    // Set the boolean to false
    keepfetchingPosts = false;

    // Return the JSON of the successfull response.
    return apiResults.data;

} else if (apiResults.status === 200) {

    // If the status code is 200, then return the JSON of the successfull response 
    return apiResults.data;

} else {

    // Otherwise, set the boolean to false
    keepfetchingPosts = false; 

}
}
// Defining a constant variable that holds and async fynction. An async functon will always return a promise. 
// The function takes one argument, which is set to 1 by default.
const getEntirePostList = async function(pageNo = 1) {

// Try and catch statement used to handle the errors that might occur. 
try {
        // Constant variable which is set to the return variable of the function getPost(). Get post returns the successfull paginated response of the request. 
        const results = await getPosts(pageNo);

        // Logging out a string including the length of the array.
        console.log('Current array contain ' + results.length + ' items...');

        // Conditional statement that checks if the length of the array named 'results' is less than the variable named limitPerPage. Condition is also checked, if bolean is true. 
        // If the conditions are met, the code will join the arrays into one big array.  
        if (results.length < limitPerPage && keepfetchingPosts === true) {

            // Logging out a string that indicates an attempt to combine that last array to the existing array. 
            console.log('Combining last array!');

            // Return the combined array. 
            return results;

        } else if (keepfetchingPosts === true) {

            // Logging out a string that indicates an attempt to combine the recent fetched array to the existing array.   
            console.log('Combining arrays!');

            // Returning the new combined array and increments the pageNo variable with 1. 
            return results.concat(await getEntirePostList(pageNo+1));

        } else {

            // Logging out a string that indicates the script will stop fetching more posts from the REST API.  
            console.log('Stop fetching posts and return results');

            // Returning the complete array. 
            return results;

        }
    // Catch statement that takes the argument of the error that occured. 
    } catch(error) {

        // Logging out the error. 
        console.log(error);

    }

};( async () => {

    // Constant variable with the assigned value received from the function 
    const entireList = await getEntirePostList();

    // Logging out the enite list of results collected from the REST API
    console.log(entireList);

})
();

Приведенный выше код возвращает полный массив ответов JSON от всех вызовов API REST с разбивкой по страницам.

0 голосов
/ 11 июля 2019

Вы можете использовать цикл while и уменьшить limitPerPage, если код состояния не равен 200:

console.log('REST API is this: ' + apiUrl);

const getPosts = async pageNo => {
  let limitPerPage = 20;
  let requestUrl = apiUrl + `?page=${pageNo}&per_page=${limitPerPage}`;
  let res = { status: 0 }
  while (res.status !== 200) {
    res = await fetch(requestUrl)
      .then(r => ({ data: r.json(), status: r.status }))
      .catch(({status}) => console.log(status))
    limitPerPage--
  }
  return res.data
}

const getEntirePostList = async (pageNo = 1) => {
  const results = await getPosts(pageNo);
  console.log('Retreiving data from API for page : ' + pageNo);

  return results.length > 0 
    ? results.concat(await getEntirePostList(pageNo + 1))
    : results;
}

(async () => {
  const entireList = await getEntirePostList();
  console.log(entireList);
})()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...