如何在 rxjs 中*完全*完成第一个之后*仅*启动第二个可观察对象

How to start second observable *only* after first is *completely* done in rxjs

我的印象是 Observable.[prototype.]concat 确保第一个操作在第二个操作开始之前完全完成。但是在下面的代码中:

Observable
    .concat(
        Observable.fromNodeCallback(rimraf)(path.resolve('./some_dir')),
        Observable.fromNodeCallback(mkdir)(path.resolve('./some_dir')),
        writeToSomeDir$
    )

mkdir 尝试(但失败)在 rimraf 删除目录之前创建 ./some_dir。然而,在(投掷)结束时,./some_dir 最终被删除。

为什么 Observable.concat 表现出这种行为?我怎样才能确保第一个 Observable 在开始第二个 Observable 之前完全完成而不落入 rimraf 的同步版本?

问题在于 fromNodeCallback 创建了一个函数,该函数在被调用时会执行底层函数,并且 return 通过 Observable 调用的结果。本质上,Observable return 值正在替换您通常必须作为函数的最后一个参数传递的节点样式回调。但是,该函数仍会立即被调用。

如果您想延迟方法的执行,您可以将它们包装在 defer 中以防止它们在订阅 Observables 之前执行。

var rimrafObservable = Observable.fromNodeCallback(rimraf);
var mkdirObservable = Observable.fromNodeCallback(mkdir);

Observable
    .concat(
        Observable.defer(() => rimrafObservable(path.resolve('./some_dir'))),
        Observable.defer(() => mkdirObservable(path.resolve('./some_dir'))),
        writeToSomeDir$
    );