Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redux传奇未等待Firebase服务返回_Redux_Redux Saga - Fatal编程技术网

Redux传奇未等待Firebase服务返回

Redux传奇未等待Firebase服务返回,redux,redux-saga,Redux,Redux Saga,SignUpSaga坏了。它不等待“yield put(updateUserAction(user));”返回值,它只返回未定义的值,然后断开应用程序,注册服务随后返回 我如何让它等待?我以为这就是屈服所做的 redux软件包的部分: export const updateUserAction = (user: User | null): UpdateUserActionType => ({ type: UPDATE_USER, user, }); 互动者 export cla

SignUpSaga坏了。它不等待“yield put(updateUserAction(user));”返回值,它只返回未定义的值,然后断开应用程序,注册服务随后返回

我如何让它等待?我以为这就是屈服所做的

redux软件包的部分:

export const updateUserAction = (user: User | null): UpdateUserActionType => ({
  type: UPDATE_USER,
  user,
});

互动者

export class SignUpInteractor {
  signUpService: SignUpService;

  constructor(signUpService: SignUpService) {
    this.signUpService = signUpService;
  }

  async signUp(
    firstName: string,
    lastName: string,
    credential: Credential
  ): Promise<User> {
    const user = new User(firstName, lastName, credential.email);
    return this.signUpService.signUpUser(user, credential);
  }

}
最后,注册服务:

export class FirebaseLogin implements SignUpService {
  async signUpUser(user: User, credential: Credential): Promise<User> {
    var user: User;

    try {
      db.app
        .auth()
        .createUserWithEmailAndPassword(credential.email, credential.password)
        .then((authData) => {
          db.app
            .database()
            .ref("users/" + authData.user.uid)
            .set({
              uid: authData.user.uid,
              email: credential.email,
              firstName: user.firstName,
              lastName: user.lastName,
            })
            .then(() => {
              db.app
                .database()
                .ref("users/" + authData.user.uid)
                .once("value")
                //do this to make sure data was returned as values, not resolved later by firebase.
                .then((snapchat) => {})
                .then(() => {
                  console.log("returning");
                  return user;
                });
            })
            .catch((error) => {
              return new User("error", "error", "err@err.com");
            });
        })
        .catch((error) => {
          console.log("error here");
          return new User("error", "error", "err@err.com");
        });
    } catch (error) {
      console.log("error here");
      return new User("error", "error", "err@err.com");
    }
  }
导出类FirebaseLogin实现SignUpService{
异步注册用户(用户:用户,凭证:凭证):承诺{
var用户:用户;
试一试{
db.app
.auth()
.createUserWithEmailAndPassword(credential.email,credential.password)
。然后((authData)=>{
db.app
.数据库()
.ref(“users/”+authData.user.uid)
.设置({
uid:authData.user.uid,
电子邮件:credential.email,
firstName:user.firstName,
lastName:user.lastName,
})
.然后(()=>{
db.app
.数据库()
.ref(“users/”+authData.user.uid)
.一次(“价值”)
//执行此操作以确保数据作为值返回,而不是稍后由firebase解析。
.然后((snapchat)=>{})
.然后(()=>{
控制台日志(“返回”);
返回用户;
});
})
.catch((错误)=>{
返回新用户(“错误”、“错误”、”err@err.com");
});
})
.catch((错误)=>{
console.log(“此处出错”);
返回新用户(“错误”、“错误”、”err@err.com");
});
}捕获(错误){
console.log(“此处出错”);
返回新用户(“错误”、“错误”、”err@err.com");
}
}

我认为主要的问题是如何使用
呼叫

const user=yield call(()=>{
注册(名字、姓氏、凭证);
});
您正在传递一个同步函数,该函数将启动一个异步调用并立即返回。此外,该函数不返回任何内容,因此
未定义

您真正想要的是告诉中间件进行异步调用,然后等待承诺得到解决:

const user=yield call(interactior.signUp、firstName、lastName、credential);
此外,您的代码看起来比需要的复杂得多:手工编写Redux代码,在Reducer中使用额外的函数,为action对象定义单独的TS类型,以及这个“Interactior”和“service”在本例中,即使使用sagas也有点过分。您应该使用并遵循我们的建议,在TS中使用Redux。这将大大简化您的代码

如果是我自己写的,我会让
注册
部分成为一个独立的异步函数,并使用RTK的
createAsyncThunk

async function signUpUser(user: User, credential: Credential): Promise<User> {
  // omit Firebase code
  return user;
}

interface SignUpArgs {
  firstName: string;
  lastName: string;
  credential: Credential;
}

const signUp = createAsyncThunk(
  'users/signUp',
  async ({firstName, lastName, credential}: SignUpArgs) => {
    const user = new User(firstName, lastName, credential.email);
    return signUpUser(user, credential);
  }
)

type UserState = User | null;
const initialState : UserState = null;

const userSlice = createSlice({
  name: 'users',
  initialState, // whatever your state actually is,
  reducers: {
    // assorted reducer logic here
    signOut(state, action) {
      return null;
    }
  },
  extraReducers: builder => {
    builder.addCase(signUp.fulfilled, (state, action) => {
      return action.payload
    });

  }
})
异步函数注册用户(用户:用户,凭证:凭证):承诺{
//省略Firebase代码
返回用户;
}
接口注册参数{
名字:字符串;
lastName:string;
凭证:凭证;
}
const signUp=createAsyncThunk(
“用户/注册”,
异步({firstName,lastName,credential}:SignUpArgs)=>{
const user=新用户(名字、姓氏、凭证、电子邮件);
返回注册用户(用户、凭证);
}
)
类型UserState=User | null;
const initialState:UserState=null;
const userSlice=createSlice({
名称:'用户',
initialState,//无论您的实际状态是什么,
减速器:{
//这里有各种各样的逻辑
注销(状态、操作){
返回null;
}
},
外部减速器:生成器=>{
builder.addCase(signUp.completed,(state,action)=>{
返回动作.有效载荷
});
}
})

最后的代码要少得多,特别是当你在还原程序中进行任何实际有意义的状态更新时。

改为使用Redux Toolkit。要修复此问题,我还必须在验证结果时使用return new Promise((resolve)=>{…resolve(user);}包装我的注册函数。我现在可以处理CreateAncySthunk(..)中的错误了.我以前也遇到过麻烦。
export class FirebaseLogin implements SignUpService {
  async signUpUser(user: User, credential: Credential): Promise<User> {
    var user: User;

    try {
      db.app
        .auth()
        .createUserWithEmailAndPassword(credential.email, credential.password)
        .then((authData) => {
          db.app
            .database()
            .ref("users/" + authData.user.uid)
            .set({
              uid: authData.user.uid,
              email: credential.email,
              firstName: user.firstName,
              lastName: user.lastName,
            })
            .then(() => {
              db.app
                .database()
                .ref("users/" + authData.user.uid)
                .once("value")
                //do this to make sure data was returned as values, not resolved later by firebase.
                .then((snapchat) => {})
                .then(() => {
                  console.log("returning");
                  return user;
                });
            })
            .catch((error) => {
              return new User("error", "error", "err@err.com");
            });
        })
        .catch((error) => {
          console.log("error here");
          return new User("error", "error", "err@err.com");
        });
    } catch (error) {
      console.log("error here");
      return new User("error", "error", "err@err.com");
    }
  }
async function signUpUser(user: User, credential: Credential): Promise<User> {
  // omit Firebase code
  return user;
}

interface SignUpArgs {
  firstName: string;
  lastName: string;
  credential: Credential;
}

const signUp = createAsyncThunk(
  'users/signUp',
  async ({firstName, lastName, credential}: SignUpArgs) => {
    const user = new User(firstName, lastName, credential.email);
    return signUpUser(user, credential);
  }
)

type UserState = User | null;
const initialState : UserState = null;

const userSlice = createSlice({
  name: 'users',
  initialState, // whatever your state actually is,
  reducers: {
    // assorted reducer logic here
    signOut(state, action) {
      return null;
    }
  },
  extraReducers: builder => {
    builder.addCase(signUp.fulfilled, (state, action) => {
      return action.payload
    });

  }
})