如何使用Ramda从Jira API返回整个页面集?

时间:2019-04-23 20:34:18

标签: functional-programming jira-rest-api ramda.js

我正在使用Nodejs库与称为jira-connector的Jira进行通信。我可以通过调用

来获得jira实例上的所有面板
jira.board.getAllBoards({ type: "scrum"})
  .then(boards => { ...not important stuff... }

返回集如下所示:

{ 
  maxResults: 50,
  startAt: 0,
  isLast: false,
  values:
   [ { id: ... } ]
}

然后,当 isLast === false 时,我一直这样打电话:

jira.board.getAllBoards({ type: "scrum", startAt: XXX })

直到 isLast 为真。然后我就可以整理我所有的诺言回报并完成它。

我正试图弄清楚如何使用Ramda来获取页面上的所有数据,我有一种感觉,就是我似乎无法弄清如何处理。

有帮助吗?可以使用Ramda吗?

3 个答案:

答案 0 :(得分:0)

这是我的Rx尝试做得更好:

const pagedCalls = new Subject();

pagedCalls.subscribe(value => {
    jira.board.getAllBoards({ type:"scrum", startAt: value })
        .then(boards => {
            console.log('calling: ' + value);
            allBoards.push(boards.values);
            if (boards.isLast) {
                pagedCalls.complete()
            } else {
                pagedCalls.next(boards.startAt + 50);
            }

        });
})
pagedCalls.next(0);

似乎很可怕。这是到目前为止用do / while循环获得的最简单的解决方案:

let returnResult = [];
let result;
let startAt = -50;

do {

  result = await jira.board.getAllBoards( { type: "scrum", startAt: startAt += 50 })
  returnResult.push(result.values); // there's an array of results under the values prop. 

} while (!result.isLast)  

许多与Jira的交互都使用此模型,因此我试图避免每次打电话时都编写这种循环。

答案 1 :(得分:0)

我今天必须做类似的事情,重复调用Gitlab API,直到我检索了项目的整个文件夹/文件结构。我是在.then内部进行递归调用的,它似乎可以正常工作。我没有尝试转换代码来处理您的情况。

这是我写的,如果有帮助的话:

const getAll = (project, perPage = 10, page = 1, res = []) =>
  fetch(`https://gitlab.com/api/v4/projects/${encodeURIComponent(project)}/repository/tree?recursive=true&per_page=${perPage}&page=${page}`)
    .then(resp => resp.json())
    .then(xs => xs.length < perPage
            ? res.concat(xs)
            : getAll(project, perPage, page + 1, res.concat(xs))
         )
 
getAll('gitlab-examples/nodejs')
  .then(console.log)
  .catch(console.warn)

这项技术非常简单:我们的函数接受能够获取特定页面所需的任何参数,并接受另一个保存结果的参数,默认为空数组。我们进行异步调用以获取页面,在then中,我们使用结果来查看是否需要进行另一个调用。如果这样做,我们将再次调用该函数,并传入其他所需的参数,递增的页码以及当前结果与刚刚接收到的结果的合并。如果我们不需要拨打其他电话,则只需返回该合并列表即可。

在这里,存储库包含21个文件和文件夹。一次调用十个,我们进行三个访存,当第三个访存完成时,我们用21个项目清单解决返回的Promise。

这种递归方法肯定比上面的版本更具功能性。除了参数defaulting外,没有其他分配,并且在此过程中没有任何变化。

我认为将其适应您的需求应该相对容易。

答案 2 :(得分:0)

这里是一种使用rubico获取所有木板的方法:

import { pipe, fork, switchCase, get } from 'rubico'

const getAllBoards = boards => pipe([
  fork({
    type: () => 'scrum',
    startAt: get('startAt'),
  }),
  jira.board.getAllBoards,
  switchCase([
    get('isLast'),
    response => boards.concat(response.values),
    response => getAllBoards(boards.concat(response.values))({
      startAt: response.startAt + response.values.length,
    })
  ]),
])

getAllBoards([])({ startAt: 0 }) // => [...boards]

getAllBoards将递归获取更多板并追加到boards直到isLast为true,然后它将返回聚合的boards