最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

Rxjs bindNodeCallback无法与swithmap和flatmap一起正常使用

IT培训 admin 16浏览 0评论

Rxjs bindNodeCallback无法与swithmap和flatmap一起正常使用

我正在尝试使用bindNodeCallback和fs readdir,stat读取文件。

这是我的代码:

import { readdir, stat, Stats } from "fs";
import { bindNodeCallback, Observable, of } from "rxjs";
import { catchError, filter, flatMap, map, mergeMap, switchMap, tap } from 'rxjs/operators';

const readDirBindCallback: (path: string) => Observable<string[]> = bindNodeCallback(readdir);
const fileStateBindCallback: (path: string) => Observable<Stats> = bindNodeCallback(stat);

readDirBindCallback('/Users/.../WebstormProjects/copy')
    .pipe(
        flatMap(x => x),
        tap(console.log),
        switchMap(status => {
            console.log(status);
            return fileStateBindCallback('/Users/.../WebstormProjects/copy/' + status);
        })
    )
    .subscribe(result => {
        console.log(result)
    });


“ switchMap”已被正确调用多次。

问题是fileStateBindCallback仅被调用一次,最终的子记录仅被记录一次。

为什么会这样?如果我在switchMap块中手动订阅fileStateBindCallback。它会按我的预期运行。但这不是一个好习惯,也不适合我的要求。

回答如下:

我认为问题是switchMap运算符。

switchMap一次只能观察一个活动的内部。如果一个外部值进入并且有一个活动的内部对象,它将被取消订阅,并且基于新到达的值提供的功能到[ C0]。[switchMap将返回一个readdir

array将只发出数组的项目

separately

synchronously假设您的目录中有flatMap(arr => arr)个项目。

N将一一发射这些项目。因此,将传递flatMap,并且item 1将创建一个内部obs(switchMap),其中涉及异步操作。然后,发送fileStateBindCallback,但由于这是同步发生的,将取消订阅由item 2处理的当前内部可观察对象(由于[C​​0]而创建的一个内部对象),并将为item 1创建一个新的内部可观察对象。

依此类推,直到switchMap终于到来。请记住,数组的项目是同步发出的。 item 2的内部Obs。将取消订阅,并为item N创建一个新的。但是由于item N-1是数组中的最后一项,所以它不能被任何后续的发射中断,这意味着它的内部可观察对象将有时间发射和完成。

您可能正在寻找的是item N

N个项目到达时,对于根据第concatMap个项目创建的当前内部可观测对象,它将

wait

complete,然后根据N个项目。因此,用N-1替换N应该可以完成工作。如果顺序不重要,则可以选择switchMap

Rxjs bindNodeCallback无法与swithmap和flatmap一起正常使用

我正在尝试使用bindNodeCallback和fs readdir,stat读取文件。

这是我的代码:

import { readdir, stat, Stats } from "fs";
import { bindNodeCallback, Observable, of } from "rxjs";
import { catchError, filter, flatMap, map, mergeMap, switchMap, tap } from 'rxjs/operators';

const readDirBindCallback: (path: string) => Observable<string[]> = bindNodeCallback(readdir);
const fileStateBindCallback: (path: string) => Observable<Stats> = bindNodeCallback(stat);

readDirBindCallback('/Users/.../WebstormProjects/copy')
    .pipe(
        flatMap(x => x),
        tap(console.log),
        switchMap(status => {
            console.log(status);
            return fileStateBindCallback('/Users/.../WebstormProjects/copy/' + status);
        })
    )
    .subscribe(result => {
        console.log(result)
    });


“ switchMap”已被正确调用多次。

问题是fileStateBindCallback仅被调用一次,最终的子记录仅被记录一次。

为什么会这样?如果我在switchMap块中手动订阅fileStateBindCallback。它会按我的预期运行。但这不是一个好习惯,也不适合我的要求。

回答如下:

我认为问题是switchMap运算符。

switchMap一次只能观察一个活动的内部。如果一个外部值进入并且有一个活动的内部对象,它将被取消订阅,并且基于新到达的值提供的功能到[ C0]。[switchMap将返回一个readdir

array将只发出数组的项目

separately

synchronously假设您的目录中有flatMap(arr => arr)个项目。

N将一一发射这些项目。因此,将传递flatMap,并且item 1将创建一个内部obs(switchMap),其中涉及异步操作。然后,发送fileStateBindCallback,但由于这是同步发生的,将取消订阅由item 2处理的当前内部可观察对象(由于[C​​0]而创建的一个内部对象),并将为item 1创建一个新的内部可观察对象。

依此类推,直到switchMap终于到来。请记住,数组的项目是同步发出的。 item 2的内部Obs。将取消订阅,并为item N创建一个新的。但是由于item N-1是数组中的最后一项,所以它不能被任何后续的发射中断,这意味着它的内部可观察对象将有时间发射和完成。

您可能正在寻找的是item N

N个项目到达时,对于根据第concatMap个项目创建的当前内部可观测对象,它将

wait

complete,然后根据N个项目。因此,用N-1替换N应该可以完成工作。如果顺序不重要,则可以选择switchMap
发布评论

评论列表 (0)

  1. 暂无评论