在redux-saga调用所调用的函数中,对“ this”的引用为null

时间:2019-10-15 15:12:49

标签: javascript typescript closures redux-saga

我正在学习redux-saga,并尝试将其集成到使用由openapi-generator生成的API的项目中,该项目会产生如下所示的输出:

async loginUser(body: Login): Promise<LoginResponse> {
    debugger;
    const response = await this.loginUserRaw({ body: body });
    return await response.value();
}

loginUserRaw是执行实际登录的功能。然后,我有以下传奇故事:

function* login(action:Login) {
    try{
        const response = yield call(User.loginUser, action);
        yield result(LOGIN_SUCCESS, response)
    }catch(e){
        yield result(LOGIN_FAILURE, e)
    }
}

运行此命令时,我在API方法的await this.loginUserRaw({ body: body });行中收到错误:

TypeError: Cannot read property 'loginUserRaw' of null

我调试了一下,发现this为空。当我在传奇中明确绑定函数时:

const response = yield call(User.loginUser.bind(User), action);

它可以工作,但是我不想每次调用函数时都将其绑定。如何在没有显式绑定功能的情况下使传奇工作? (我也无法更改生成的代码并删除this

2 个答案:

答案 0 :(得分:1)

基于您编写代码的方式,Javascript中的上下文是动态的

const loginUser = User.loginUser
loginUser() // context lost, because there is no longer `User.` in front of it

将函数作为参数传递时,同样适用。这意味着您必须以某种方式提供call效果上下文。 bind方法是一种选择,但是效果本身支持多种提供上下文的方式。您可以在官方文档https://redux-saga.js.org/docs/api/#callcontext-fn-args中找到它们,以下是它的简短版本:

传递上下文的可能方法:

call([context, fn], ...args)
call([context, fnName], ...args)
call({context, fn}, ...args)

例如,您可以执行以下操作:

const response = yield call([User, User.loginUser], action);

答案 1 :(得分:0)

loginUser被当作静态方法使用。

使用该类之前,您需要实例化该类,

function* login(action:Login) {
    try{
        const user = new User()
        const response = yield call(user.loginUser, action);
        yield result(LOGIN_SUCCESS, response)
    }catch(e){
        yield result(LOGIN_FAILURE, e)
    }
}