简体   繁体   中英

How to chain Observables produced by a generator function?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM