возвращать данные на основе URL-адресов выборки - PullRequest
0 голосов
/ 09 ноября 2018

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

flatMap использовался для преобразования promise в объект, но, похоже, я ошибался. Пожалуйста, дайте мне знать, как я могу это исправить.

/** Receives UpdateEvent */
const changes$ = new Subject<FileChangesEvent>();

/** mock for 'this' */
const context = {
    notify: (...args) => console.log('[CONTEXT.NOTIFY]: ', ...args),
    processAdds: (input) => of(input).pipe(delay(input.debounce || 1), map(i => Object.assign(i, ...fetch(i.url)))),
    processUpdates: (input) => of(input).pipe(delay(input.debounce || 1), map(i => Object.assign(i, ...fetch(i.url)))),
    processDeletes: (input) => of(input).pipe(delay(input.debounce || 1), map(i => Object.assign(i, { modified: 'fetchUpdates' }))),
};

/** Process FilesChange event */
const stream$ = changes$
    .pipe(
        /** Side effect for log current step */
        tap(event => console.log('onFileChanges trigged, event data: ', event.changes)),
        /** Fetching array of changes */
        map(event => event.changes),
        /** Use it for wait all 'forked' observables */
        flatMap(
            /** Process each record in parallel */
            changes => forkJoin(
                changes.map(change =>
                    /** Update processing */
                    of(change)
                        .pipe(
                            tap(input => console.log('Validating the file Type: ', input)),
                            /** fetching data based on update type */
                            flatMap(input =>
                                input.type === FileChangeType.ADDED
                                    ? context.processAdds(input)
                                    : context.processUpdates(input),
                            ),
                            /** remove large files from update */
                            map(input => (
                                input.type === FileChangeType.UPDATED && input.size < CONTENT_SIZE_LIMIT
                                    ? Object.assign(input, { value: '' })
                                    : input
                            )),
                            /** side effect for pubsub notifications */
                            tap(updates => context.notify(updates)),
                        ),
                ),
            ),
        ),
    );

/** When updates stream was finished */
stream$.subscribe(
    (...args) => console.log('[TICK]: ', ...args), // When all event updates was processed
    (...args) => console.log('[ERROR]: ', ...args),
    (...args) => console.log('[DONE]: ', ...args),
);

export const updateEventsStream = (event) => changes$.next(event);

1 Ответ

0 голосов
/ 10 ноября 2018

Я вижу две проблемы в вашем коде. Первое - это разрушение обещания - map(i => Object.assign(i, ...fetch(i.url))). Это уничтожит его полностью, и вы не сможете получить от него результат. Если вам нужно изменить значение, возвращаемое из API, используйте then: map(i => fetch(i.url).then(val => Object.assign(i, ...val))).

Хорошо, следующая проблема точно с наблюдаемыми. Вы правильно используете flatMap, чтобы развернуть значение, возвращаемое из processAdds (и других), но дело в том, что эти функции возвращают обещание, заключенное в наблюдаемое. Вы начинаете с создания наблюдаемого из ввода: of(input) и затем map ввода для обещания. Следовательно, когда вы разворачиваете результат в flatMap, вы получаете обещание, а не его ценность.

Простым решением было бы развернуть обещание внутри вспомогательных функций, используя любые операторы <something>Map, например. тот же flatMap:

processAdds: (input) =>
  of(input).pipe(delay(input.debounce || 1), flatMap(i => fetch(i.url))),

Полный пример вы можете посмотреть здесь - https://stackblitz.com/edit/rxjs-fetch-flatmap?devtoolsheight=60

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...