Javascript 如何在更改url之前等待成功的异步操作?

Javascript 如何在更改url之前等待成功的异步操作?,javascript,reactjs,asynchronous,redux,async-await,Javascript,Reactjs,Asynchronous,Redux,Async Await,因此,我使用弹出窗口让我的用户登录firebase: const loginToApp = (provider) => { firebaseApp .auth() .signInWithPopup(provider) .then(async (result) => { if (result.additionalUserInfo.isNewUser) { // problem

因此,我使用弹出窗口让我的用户登录firebase:

const loginToApp = (provider) => {
    firebaseApp
        .auth()
        .signInWithPopup(provider)
        .then(async (result) => {
            if (result.additionalUserInfo.isNewUser) {
                // problem is this line
                await setNewUserInformation(result.user.uid)
            }
            const { user } = result
            setUser(user)
            // and this line
            window.location.href = 'newRoute'
        })
        .catch((error) => {
            console.log('ERROR:', error)
        })
}
因此,如果我删除
window.location.href='visted'
这一切都可以正常工作,并在firebase中设置。我可能在做一些愚蠢的事情,但我不知道如何等待此函数启动
setNewUserInformation
并在移动到新页面之前完成

功能代码:

export const setNewUserInformation = (userId) => {
    return {
        type: 'SET_NEW_USER_INFORMATION',
        userId,
    }
}
然后有一个可观察到的redux史诗在听:

return action$.pipe(
    ofType('SET_NEW_USER_INFORMATION'),
    mergeMap((action) => {
        return from(
            firebaseApp.database().ref(firebaseRef).update(userInformation),
        ).pipe(
            mergeMap(() => {
                return [updatedUserInformationSuccess()]
            }),
            catchError((error) => of(updatedUserInformationFailure(error))),
        )
    }),
)
像下面那样使用它

const loginToApp = (provider) => {
firebaseApp
    .auth()
    .signInWithPopup(provider)
    .then(async (result) => {
        new Promise((resolve, reject) => {
             if (result.additionalUserInfo.isNewUser) {
                // problem is this line
                setNewUserInformation(result.user.uid)
            }
           const { user } = result
           resolve(user)
        }).then((user)=>{
          setUser(user)
          // and this line
          window.location.href = 'newRoute'
        })
       
    })
    .catch((error) => {
        console.log('ERROR:', error)
    })
  }

因为在
上,您可以返回承诺并稍后解决。我们可以像下面这样重新编写上面的代码:

const loginToApp = (provider) => {
    firebaseApp
        .auth()
        .signInWithPopup(provider)
        .then((result) => {
            if (result.additionalUserInfo.isNewUser) {
                // return for next resolve function
                return setNewUserInformation(result.user.uid).then(() => result); 

            }
            return result;
        })
        .then((result) => {
            // after all above promises resolve
            const { user } = result
            setUser(user)
            // and this line
            window.location.href = 'newRoute'
        })
        .catch((error) => {
            console.log('ERROR:', error)
        })
}
你在用React吗?
如果是,则在成功调度操作后,您可以简单地使用diddupdate Cycle路由到新的url。将您的“window.location.href=‘newRoute’”移动到ComponentDidUpdate with props检查下。

setNewUserInformation()
是一个动作创建者,它是同步的。您不需要等待它,因为它不会返回任何对您有用的逻辑。您需要做的是将
window.location.href='newRoute'
移动到单独的逻辑,并使其取决于操作创建者返回的状态
updateUserInformation成功()
和updateUserInformation失败(错误)。如果您的组件功能正常,请将此逻辑置于
useffect
中。如果它是类组件,请使用
componentdiddupdate
lifecycle方法。

函数的外观如何?@Ifaruki我将添加代码。但它只是一个动作创造者,然后有一个可观察到的重复聆听it@Ifaruki添加的codewell事实是,您正在对函数使用
await
,而该函数没有返回承诺。我认为
from
在redux中返回承诺。我正在使用一个函数组件。我知道我仍然可以和他们一起做这件事,但问题是我的redux,我想,无论如何,这对我有帮助。移动到useEffect,然后在切换页面之前等待redux更新。干杯,兄弟!如果你不介意的话,把这个问题加上记号;)