首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FP-TS:映射响应

FP-TS:映射响应
EN

Stack Overflow用户
提问于 2022-09-15 15:10:31
回答 1查看 77关注 0票数 1

我正在使用fp-ts库,我无法理解如何实现以下场景:

  1. ,假设我有一个请求方法getBooks(大陆架,页面)的服务,响应看起来如下(请求是分页的):

代码语言:javascript
复制
{ 
    totalItems: 100,  
    perPage: 25,  
    books:[{...}, ...],  
    ....
}

  1. ,所以我想发送一个初始请求,然后计算页面数:

代码语言:javascript
复制
const nrOfPages = Math.ceil(totalItems / perPage);

  1. ,然后循环获得其余的书籍,作为第一个请求,将只提供给我前25本书。

现在的斗争是,最后,我想收集所有的书在一个物体内。基本上,我想等待结果和平面图他们在一起。同样重要的是,请求应该是顺序的,并且使用fp库。

代码语言:javascript
复制
const allBooks [{...},{...},{...}, ...];
EN

回答 1

Stack Overflow用户

发布于 2022-09-25 05:56:36

您可以从traverseSeqArray模块中使用Task将一个页码数组映射到任务中,以获取每个页面,并且每个任务都将按顺序执行。然后,您可以使用concatAll (来自Monoid)连接书籍数组。

代码语言:javascript
复制
declare const traverseSeqArray: <A, B>(f: (a: A) => Task<B>) => (as: readonly A[]) => Task<readonly B[]>
declare const concatAll: <A>(M: Monoid<A>) => (as: readonly A[]) => A
代码语言:javascript
复制
import * as M from 'fp-ts/lib/Monoid';
import * as RA from 'fp-ts/lib/ReadonlyArray';
import * as T from 'fp-ts/lib/Task';
import {flow, pipe} from 'fp-ts/lib/function';

declare const getBooks: (
    shelf: Shelf,
    page: number
) => T.Task<{totalItems: number; perPage: number; books: readonly Book[]}>;

const getAllBooks = (shelf: Shelf): T.Task<readonly Book[]> =>
    pipe(
        // Fetch the first page (assuming pages are zero-indexed)
        getBooks(shelf, 0),
        T.chain(({totalItems, perPage, books: firstPageBooks}) => {
            const nrOfPages = Math.ceil(totalItems / perPage);
            // e.g. [1, 2, 3] for 100 books and 25 per page
            const pagesToFetch = Array.from(
                {length: nrOfPages - 1},
                (_, i) => i + 1
            );
            return pipe(
                pagesToFetch,
                // With each page...
                T.traverseSeqArray(page =>
                    // ...fetch the books at the page
                    pipe(
                        getBooks(shelf, page),
                        T.map(({books}) => books)
                    )
                ),
                // Now we have a Task<Book[][]> that we want to turn into
                // a Task<Book[]> including the books from the first page
                T.map(
                    flow(
                        // Prepend the first pages’ books
                        RA.prepend(firstPageBooks),
                        // Concatenate the Book[][] into a Book[]
                        M.concatAll(RA.getMonoid())
                    )
                )
            );
        })
    );

本例假设getBooks没有失败,但是可以通过将Task切换到TaskEither轻松地修改tihs。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73733553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档