问题
I was under impression that Observable.[prototype.]concat makes sure first operation is fully finished before second operation starts. But in following code:
Observable
.concat(
Observable.fromNodeCallback(rimraf)(path.resolve('./some_dir')),
Observable.fromNodeCallback(mkdir)(path.resolve('./some_dir')),
writeToSomeDir$
)
mkdir attempts (and fails) to create ./some_dir before rimraf is finished deleting the dir. At the end (of throwing) however, ./some_dir ends up getting deleted.
Why is Observable.concat showing such behaviour? How can I make sure first Observable is fully finished before starting with second Observable without falling to sync version of rimraf?
回答1:
The problem is that fromNodeCallback creates a function that when invoked executes the underlying function and returns the result of the invocation through an Observable. Essentially the Observable return value is replacing the node style callback you would normally have to pass as the last argument to the function. However, the function still gets invoked immediately.
If you want to delay the execution of the methods you can wrap them in defer to prevent their execution until the Observables are subscribed to.
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$
);
来源:https://stackoverflow.com/questions/33720112/how-to-start-second-observable-only-after-first-is-completely-done-in-rxjs