Let's say I have a generator function that returns multiple observables corresponding to sequence of operations it needs to perform. The catch here is that the result from one operation may be explicitly used in others, or in the generator function itself
Eg:
* doImportFile(fileName) {
let foo = false
yield bindNodeCallback(fsextra.readdir)(fileName).pipe(map(r => {
foo = true
return 0
}))
if (foo) {
yield of(1)
} else {
yield of(2)
}
}
Now, if you chain these together using something like
concat(doImportFile(fileName)).pipe(concatAll())
you won't get the behavior you expect. foo will be false at evaluation time and of(2) will be yielded.
The more obvious approach is to do something like this:
async performOperations(fileName) {
for(const op of doImportFile(fileName)) {
await op
}
}
and that would actually produce the results I want. The problem (obviously) is that concat takes in an array, and that array is generated without actually subscribing (or waiting for) any of the observables it yields.
So, short of looping over, is there a way of doing what I want? And if not, how would you change performOperations to return concatenated results of doImportFile's output?
My guess at this point is that the underlying issue is that I am trying to mix functional and declarative programming in my generator function. A way of solving this is moving entirely functional, eg
* doImportFile(fileName) {
let foo = false
yield bindNodeCallback(fsextra.readdir)(fileName).pipe(map(r => {
foo = true
return 0
}))
yield iif(() => foo, of(1), of(2))
}
This would actually work, but feels cumbersome. Essentially all that's needed is a concat operator that takes an iterable instead of an array... right?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.