Condição de corrida no Amplify.Hub signIn manipulador ao usar juramento


8

Código de exemplo:

Hub.listen('auth', event => {
  const { event: type, data } = event.payload;

  if (type === 'signIn') {
    const session = data.signInUserSession;
    console.log('SESSION', data.signInUserSession);
    setTimeout(() => {
      console.log('SESSION', data.signInUserSession);
    }, 100);
  }
});

Ao usar juramento, depois que o provedor redireciona para meu aplicativo, o Hub dispara um signInevento. No entanto, a signInUserSessionpropriedade é nullquando o evento é disparado, mas obtém um valor algum tempo depois (dentro de 100 ms). Isso não parece ocorrer ao usar Auth.signIn(email, password)diretamente; signInUserSessioné preenchido quando o evento é disparado.

O que está acontecendo aqui e como posso contornar isso? Atualmente, tenho um atraso explícito no código, o que é um hack terrível.


Qual é a versão que você está usando? Eu tentei reproduzir isso no app que eu estou usando não é bem sucedida
karthick

Você também pode usar a promessa em javascript.
Prabhat

Onde ou como você está ouvindo esse evento, o código faz parte de um componente ou de qualquer classe singleton?
Karthick #

Eu estou usando redux-saga e usando Hub.listenpara alimentar um canal de eventos. No entanto, também tentei executar o código de exemplo acima diretamente de uma saga e tive o mesmo problema.
Thom Smith

Respostas:


2

Talvez a maneira antiga do JavaScript de esperar que o valor seja preenchido seja útil para garantir que o código não falhe, mesmo que demore mais do que o esperado ao preencher o valor.

Aqui está um código de exemplo que eu normalmente uso quando não há outras opções disponíveis.

waitForValue(){
    if(myVar!= null && typeof myVar !== "undefined"){
        //value exists, do what you want
        console.log(myVar)
    }
    else{
        setTimeout(() => {this.waitForValue()}, 100);
    }
}

Você pode refatorar esse código de exemplo conforme sua necessidade.

Como alternativa, o AWS Amplify também tem outras maneiras de atualizar a sessão do usuário atual. por exemplo, Auth.currentAuthenticatedUser()e Auth.currentSession()devolver a promessa. Eles podem ser usados ​​assim

private async getUser(){
    let user = null;
    try {
      user = await Auth.currentAuthenticatedUser();
      //console.log(user);
    } catch (err) {
      //console.log(err);
    }
    //return user;
  }

0

eu não estou acostumado a aws amplificar - basta ler alguns github e até agora eu posso ver que precisaremos de informações sobre sua userPoolimplementação - eu acho que algum problema estranho de retorno de chamada

Mas, para uma solução alternativa, você pode proxy a referência:

const event = {type: "signIn", data: {signInProperty: "null"}}

setTimeout(()=>event.data.signInProperty = "{Stack: Overflow}", 1000)

// mock events
function emit(type, args){
  console.log(type, args)
}

//initialize
let watchedValue = event.data.signInProperty
document.getElementById("app").innerHTML = event.data.signInProperty 
// protect reference
Object.defineProperty(event.data, "signInProperty", {
    set(newValue){
      watchedValue = newValue
      document.getElementById("app").innerHTML = newValue
      emit("event:signInCompleted", event.data)
    },
    get(){
      return watchedValue
    }
})
<div id="app"></div>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.