查询大量帖子的WordPress WP-API(使用promises!)

时间:2017-08-08 20:32:57

标签: node.js wordpress promise axios wp-api

我正在开发一个Node.js应用程序,它使用WordPress JSON API作为一种无头CMS。当应用程序旋转时,我们向WP数据库查询并提取信息我们需要(使用Axios),操纵它,并暂时存储它。

足够简单 - 但CMS中的一个帖子类别有相当多的条目。出于一些令人遗憾的原因,WordPress一次将API请求限制限制为最多99个帖子,并要求我们编写一个可以发送并发API请求的循环,直到所有数据都被提取为止。

例如,如果我们有250个某些特定类型的帖子,我需要分三次点击该路由,指定每次我想要的特定“页面”数据。

根据文档https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/,我可以访问?page=查询字符串,我可以使用它来同时发送这些请求。 (即...&page=2

我还可以访问header对象中的X-WP-Total,这样就可以获得给定类别中的帖子总数。

但是,这些API调用是嵌套的promise链的一部分,整个过程需要返回一个我可以继续链接的承诺。

这个想法是让它变得动态,所以它总是会提取所有数据,然后将它作为一个巨大的帖子返回。这就是我所拥有的,是功能性的:

const request = require('axios');

module.exports = (request_url) => new Promise((resolve, reject) => {

  // START WITH SMALL ARBITRARY REQUEST TO GET TOTAL NUMBER OF POSTS FAST
  request.get(request_url + '&per_page=1').then(
    (apiData) => {

      // SETUP FOR PROMISE.ALL()
      let promiseArray = [];

      // COMPUTE HOW MANY REQUESTS WE NEED
      // ALWAYS ROUND TOTAL NUMBER OF PAGES UP TO GET ALL THE DATA
      const totalPages = Math.ceil(apiData.headers['x-wp-total']/99);

      for (let i = 1; i <= totalPages; i++) {
        promiseArray.push( request.get(`${request_url}&per_page=99&page=${i}`) )
      };

      resolve(
        Promise.all(promiseArray)
               .then((resolvedArray) => {

                 // PUSH IT ALL INTO A SINGLE ARRAY
                 let compiledPosts = [];

                 resolvedArray.forEach((axios_response) => {
                   // AXIOS MAKES US ACCESS W/RES.DATA
                   axios_response.data.forEach((post) => {
                     compiledPosts.push(post);
                   })
                 });

                 // RETURN AN ARRAY OF ALL POSTS REGARDLESS OF LENGTH
                 return compiledPosts;
               }).catch((e) => { console.log('ERROR'); reject(e);})
       )
    }
  ).catch((e) => { console.log('ERROR'); reject(e);})
})

有什么创意能让这种模式变得更好吗?

1 个答案:

答案 0 :(得分:0)

我有完全相同的问题。就我而言,我使用了Vue Resource:

this.$resource('wp/v2/media').query().then((response) => {   

  let pagesNumber = Math.ceil(response.headers.get('X-WP-TotalPages'));

  for(let i=1; i <= pagesNumber; i++) {
       this.$resource('wp/v2/media?page='+ i).query().then((response) => {
           this.medias.push(response.data);
           this.medias = _.flatten(this.medias);
           console.log(this.medias);
       });
}

我很确定有更好的解决方法来实现这一目标。