4
respostas

Return dentro de return e Future

Ainda não ficou claro pra mim esse return que retorna o openDatabase e esse future, se fala muito em retornar Future, onde tem isso na documentação?

Outra coisa, criação de variáveis sempre final, dentro do comportamento onPress foram criadas variáveis, porque? Como funciona escopo no Flutter, acesso às informações de um widget para outro ou mesmo dentro da mesma classe?

4 respostas

Olá Gisele :)

Vamos por partes

Ainda não ficou claro pra mim esse return que retorna o openDatabase 

Vou juntar essa com a explicação do Future, antes, está aqui na documentação sobre o Future e alguns exemplos

A grande questão do Future é trabalhar com assincronismo, então existe algumas operações que não são executadas diretamente pelo nosso código (abrir um banco de dados, operações de leitura e escrita, comunicação com serviços externos, ex: API's) e muitas vezes queremos fazer diversas operações com aquele valor, mas como ele ainda não está disponível o que podemos retornar é um Future, para indicar que futuramente teremos esse valor, com isso ganhamos 2 métodos:

  • then: Caso a Future consiga trazer o que desejamos, teremos o resultado dela dentro do then
  • catchError: Caso a Future tenha algum problema (banco de dados não existente, falha na conexão com o servidor), teremos o erro dentro do catchError

Para mostrar um pouco do assincronismo você pode observar esse exemplo no Dartpad que eu criei

O resultado da execução é:

Executando...
Finalizando
2005

Ou seja, quando temos uma Future, o nosso código segue a execução naturalmente, e precisamos do then para seguir um código sincrono, ou utilizar o async | await que será explicado no futuro.

Então o que o openDatabase nos retorna é uma classe do sqflite chamada Database que tem os métodos necessários para inserir e remover valores do banco

Em relação ao return com outro return é porque

  • Precisamos retornar algo para a nossa função, por isso temos o primeiro

return getDatabasesPath()

Mas essa função nos devolve uma Future e dado que temos isso, precisamos utilizar o then e caso não tenha um return dentro do then teremos um Future vazio

Outra coisa, criação de variáveis sempre final, dentro do comportamento onPress foram criadas variáveis, porque? Como funciona escopo no Flutter, acesso às informações de um widget para outro ou mesmo dentro da mesma classe?

É comum utilizarmos final para trazer imutabilidade para os nossos dados com o Flutter, no exemplo poderia ser var, mas dessa forma dentro da função do onPress poderíamos sem querer trocar o valor, utilizando final temos uma segurança maior

Após a execução do onPress o próprio flutter se encarrega de fazer a limpeza de memória para apagar as variáveis criadas como em qualquer outra linguagem

Em relação ao escopo, também teremos o padrão, um Widget tem informações apenas sobre os Widgets que tem informações publicas e que estão em um escopo acima ( pai do elemento)

Mas tipicamente essa parte de comunicação de Widgets é utilizando o InheritedWidgets ou alguma solução de bibliotecas como o Provider ( quem temos curso na plataforma também)

Conseguiu Compreender?

Qualquer coisa estou à disposição!

Abraços e Bons Estudos :)

Muito obrigada pela explicação. Eu tenho mais conhecimento em JS, o Future é equivalente a uma Promise? É um objeto?

Só essa parte que eu vou estudar um pouco mais:

Mas essa função nos devolve uma Future e dado que temos isso, precisamos utilizar o then e caso não tenha um return dentro do then teremos um Future vazio

Mas eu to entendendo melhor. Vou estudar exemplo.

Acredito que o future seja muito parecido com o Promise do js. Excelente explicação

Isso mesmo!

Você pode trabalhar com Future em Flutter da mesma forma que utiliza Promises em javascript

Mas essa função nos devolve uma Future e dado que temos isso, precisamos utilizar o then e caso não tenha um return dentro do then teremos um Future vazio

Vou trazer um pouco mais para o mundo javascript para que fique mais fácil, imagine o seguinte exemplo:

function fakeAPI(){
    return new Promise( (resolve, reject) => {
        resolve([
            {id: 1, nome: "Geovani", fav: "Clojure"},
            {id: 2, nome: "Wanderson", fav: "Typescript"},
            {id: 3, nome: "Nadia", fav: "Python"}
        ])
    })
}

function fetchDataFromAPI(){
    return fakeAPI().then( dados => {
        const finalResponse =  { sucesso: true, quantidade: dados.length, ...dados}

        return finalResponse;
    })
}

(function(){
    console.log("Buscando dados da APi....")
    fetchDataFromAPI().then(console.log)
})()

Neste exemplo o getDatabasesPath equivale ao fetchDataFromAPI, veja que ele recebe uma Promise e eu pego o conteúdo retornado pela api e chamo de dados, e faço apenas uma pequena adição

Teremos o seguinte retorno:

Buscando dados da APi....
{
  '0': { id: 1, nome: 'Geovani', fav: 'Clojure' },
  '1': { id: 2, nome: 'Wanderson', fav: 'Typescript' },
  '2': { id: 3, nome: 'Nadia', fav: 'Python' },
  sucesso: true,
  quantidade: 3
}

Se você tirar o return interno:

function fetchDataFromAPI(){
    return fakeAPI().then( dados => {
        const finalResponse =  { sucesso: true, quantidade: dados.length, ...dados}
    })
}

Teremos:

Buscando dados da APi....
undefined

Por mais que realizamos as operações internas, o then cria uma nova promise, e se ela não tem retorno, temos uma Promise<void> que traz undefined

Então no Flutter é a mesma coisa:

<--- Retorna uma Nova Promise -------->
return getDatabasesPath().then((dbPath) {
<------- Promise Interna ---------->
    final String path = join(dbPath, 'bytebank.db');
    return openDatabase(path, onCreate: (db, version){
      db.execute('CREATE TABLE contacts('
        'id INTEGER PRIMARY KEY, '
          'name TEXT, '
        'account_number INTEGER)');
    }, version: 1);
  });

Para que a promise mais externa tenha resultado é necessário que as internas sejam resolvidas e tragam retorno :)

Parece um pouco complexo, mas conforme vai fazendo requisições a API, e utilizando recurso de assincronismo, vai ficando mais fácil :)

Abraços e Bons Estudos!