gpt4 book ai didi

javascript - 带有 redux 的 RxJS - 完成时发出 Action (使用 mergeMap)

转载 作者:行者123 更新时间:2023-11-30 20:23:44 24 4
gpt4 key购买 nike

这是我目前写的史诗:

const storiesURL = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty';
const topStoryURL = id => `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
const maxAtOnce = 15;

const fetchStoriesEpic = action$ => action$.pipe(
ofType(actions.FETCH_STORIES),
debounceTime(100),
switchMap(() => ajax.getJSON(storiesURL)), // 1. After that I have an array of ids
map(ids => ids.slice(0, maxAtOnce).map(topStoryURL)), // 2. After that I have an array of 15 of the latest ids
mergeMap(urls => from(urls)), // 3. After that I have those URLs
mergeMap(url => ajax.getJSON(url), null, 3), // 4. After that I have those responses
scan((acc, val) => [...acc, val] , []), // 5. Here I accumulate the responses into an array of stories
map(stories => actions.fetchStoriesFullfilled(stories)), // 6. Here I dispatch an action, so it passes those stories once at a time as they arrive
// ignoreElements(),
);

FETCH_STORIES 处,我将状态内的 loading 属性设置为 true。我想在这些请求完成时将其设置为 false,但不是在其中一个请求完成后,而是在它们完成所有请求后(在本例中为 15 个请求)。

我怎样才能做到这一点?

顺便说一句 - 这是一种常见的模式吗?您知道我可以在哪些资源中找到用于异步操作(我将实际使用)的 RxJS 模式吗?

最佳答案

我认为您可以简化流。例如:

const { of, forkJoin, concat } = rxjs;
const { switchMap, map } = rxjs.operators;
const { ajax } = rxjs.ajax;

/**
* test action creators
*/
const actions = {
fetchStoriesStartLoading: () => ({type: 'fetchStoriesStartLoading'}),
fetchStoriesDoneLoading: () => ({type: 'fetchStoriesDoneLoading'}),
fetchStoriesFulfilled: (stories) => ({type: 'fetchStoriesFulfilled', stories}),
};

/**
* configuration
*/
const storiesURL = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty';
const topStoryURL = id => `https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`;
const maxAtOnce = 15;

/**
* this stream loads configured number of stories
*/
const stories$ = ajax.getJSON(storiesURL).pipe(
// switch to loading individual requests, forkJoin will wait until all are resolved
switchMap(ids => forkJoin(
// use only max number of ids
ids.slice(0, maxAtOnce)
// and map those to requests
.map(id => ajax.getJSON(topStoryURL(id))))),
);

/**
* this stream wraps the stories$ stream with loading/fulfilled indicators
*/
const storiesWithLoadingIndicator$ = concat(
// signal start loading
of(actions.fetchStoriesStartLoading()),

// load stories
stories$.pipe(
// signal fulfilled
map(actions.fetchStoriesFulfilled)
),

// signal done loading
of(actions.fetchStoriesDoneLoading()),
);

/**
* test
*/
storiesWithLoadingIndicator$.subscribe(console.log);

/**
* as an epic
*/
const fetchStoriesEpic = action$ => action$.pipe(
ofType(actions.FETCH_STORIES),
debounceTime(100),
switchMapTo(storiesWithLoadingIndicator$)
);
<script src="https://unpkg.com/rxjs@6.2.1/bundles/rxjs.umd.min.js"></script>

关于javascript - 带有 redux 的 RxJS - 完成时发出 Action (使用 mergeMap),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51159839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com