使用redux-saga yield调用调用外部函数似乎会导致上下文错误

dou*_*ald 3 this redux redux-saga

我有一个redux-saga观察者/传奇的设置,如下所示:

function* parseSaga(action) {

  let result = corewar.parser.parse(action.redcode)

  yield put({ type: PARSE, result })

}

export function* parseWatcher() {  
  yield takeLatest(PARSE_REQUESTED, parseSaga);
}
Run Code Online (Sandbox Code Playgroud)

我写corewar的进口npm包装在哪里。

如上编写函数时,它可以按预期工作,但是我想将调用包装到parseyield call以便可以更好地测试文档中所描述的内容:https : //redux-saga.js.org /docs/basics/DispatchingActions.html

但是,当我像下面这样包装函数调用时:

let result = yield call(corewar.parser.parse, action.redcode)
Run Code Online (Sandbox Code Playgroud)

我收到似乎来自我的npm软件包的错误,如下所示:

uncaught at parseWatcher at parseWatcher 
 at takeLatest 
 at parseSaga 
 TypeError: Cannot read property 'scanner' of null
    at Parser.parse (http://localhost:3000/static/js/bundle.js:2017:28)
    at runCallEffect (http://localhost:3000/static/js/bundle.js:43679:19)
    at runEffect (http://localhost:3000/static/js/bundle.js:43601:648)
    ... and so on
Run Code Online (Sandbox Code Playgroud)

在这种情况下,扫描程序是Parser该类的内部属性,该类在parse方法中如下所示(在打字稿中)被调用:

public parse(document: string, options?: IParseOptions): IParseResult {

    options = Object.assign({}, Parser.DefaultOptions, options || {});

    var context = this.scanner.scan(document, options);

    ... other stuff

}
Run Code Online (Sandbox Code Playgroud)

因此,看起来好像通过使用此传奇一样,它进入了我的npm包并弄乱了this引用?

似乎我需要以某种方式确保保留先前的上下文,但是我不确定如何实现此目的,因为我不知道仅通过将外部调用包装在redux-saga call函数中就会丢失它。

编辑:情节变厚

因此,这绝对是一个上下文问题,但它似乎与调用嵌套函数调用有关。我已经对npm包进行了调整,以便parse从根对象也可以看到它,现在可以看到以下结果:

作品

let result = yield call(corewar.parse.bind(corewar), action.redcode)
let result = yield call([corewar, corewar.parse], action.redcode)
Run Code Online (Sandbox Code Playgroud)

但是原始的嵌套方法没有

不起作用

let result = yield call(corewar.parser.parse.bind(corewar), action.redcode)
let result = yield call([corewar, corewar.parser.parse], action.redcode)
Run Code Online (Sandbox Code Playgroud)

我愿意公开根对象的公共接口(无论如何,它都在我的待办事项列表上),但这是预期的结果吗?还是有些古怪?

Kra*_*mir 5

这不行吗

let result = yield call(corewar.parser.parse.bind(corewar.parser), action.redcode)
Run Code Online (Sandbox Code Playgroud)

既然parse是一种方法coreware.parser而不仅仅是coreware

如果这不起作用,那为什么不这样做:

const parse = code => corewar.parser.parse(code);

let result = yield call(parse, action.redcode)
Run Code Online (Sandbox Code Playgroud)