在 sagas 中使用回调函数

Using callback functions inside sagas

好的,所以我刚刚花了一天时间弄清楚如何在 sagas 中使用回调函数。 (请保持友善,我只是在学习这个故事)

我最初的问题: 我从服务器得到一个 xml-response,在进入我的 reducer 之前,我想将它解析成一个 js 对象。因此我使用 xml2js.

调用此 xml2js 库使用回调:

parseString(xmlInput, (err, jsResult) => {
  // here I'd like to put() my success-event, however that's not possible in this scope
})

在阅读了很多关于 eventChannels 的内容后,我想出了这个解决方案:

我的频道功能:

function parseXMLAsyncronously (input) {
  return eventChannel(emitter => {
    parseString(input, (err, result) => {
      emitter(result)
      emitter(END)
    })
    return () => {
      emitter(END)
    }
  })
}

在 saga 中使用它:

const parsedJSObject = yield call(parseXMLAsyncronously, xmlFromServer)
const result = yield take(parsedJSObject)

我现在遇到的问题是,显然即使在使用回调结构时,parseString 函数仍然同步执行。所以当我到达 yield-line 时,解析已经完成,我可以永远等待,因为什么都不会再发生了。

有效的是通过替换

进行异步解析
parseString(input, (err, result) => {...}

const parser = new Parser({async: true})
parser.parseString(input, (err, result) => {...}

所以基本上我正在使一个已经阻塞的函数解除阻塞只是为了再次阻塞(屈服)它然后等待它完成。

我的问题现在很简单:有没有更聪明的方法?

为什么不直接使用 cps 效果?

try {
  const result = yield cps(parseString, input)
} catch (err) {
  // deal with error
}