Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Loop com o IF?

Olá, durante a parte do curso em que trabalhamos na listagem dos itens do IndexedDB percebi que o loop que varria cada iteração estava sendo tradado pelo if.

Segue abaixo o código da função listaTodos(), minha dúvida se concentra no cursor.onsuccess.

listaTodos() {
        return new Promise((resolve, reject) => {
            let cursor = this._connection
                .transaction([this._store], 'readonly')
                .objectStore(this._store)
                .openCursor();

            let negociacoes = [];
            cursor.onsuccess = e => {
                let atual = e.target.result;

                if(atual) {
                    let dado = atual.value;
                    let negociacao = new Negociacao(dado._data, dado._quantidade, dado._valor);

                    negociacoes.push(negociacao);

                    atual.continue();
                } else {
                    resolve(negociacoes);
                }
            }
        });
    }

Estou bem com a parte do procedimento para iterar no cursor retornado, porém, invés de um if não deveríamos ter um while()? Como isto pode estar funcionando?

3 respostas
solução!

Jefferson! Diferente, não? Vou explicar o que acontece. É um pouco atípico do que estamos acostumados.

O callback (a função) passada para cursor.onsuccess será chamada caso a operação de buscar os dados tenha sido realizada com sucesso. Até ai tudo bem?

O lance é esse aqui:

let atual = e.target.result;

Atual é o retorno de e.target.result que é um ponteiro para o primeiro objeto retornado para o banco. No entanto, se não houver dados no banco ou se já tivermos iterado por todos os dados ele será undefined/null.

Sendo assim, testamos se atual é um valor válido e a partir dele extraímos o dado do banco. Dai, chamamos atual.continue(). Isso fará com que o callback passado para cursor.onsuccess seja chamado outra vez, mas dessa vez atual apontará para o próximo dado da store. Veja que repetimos o processo e a cada chamada de cursor.onsuccess temos acesso ao próximo objeto, o que não deixa de ser um loop. Mas não podemos chamar mais atual.continue() caso tenhamos chegado ao último objeto da store ou a store esteja vazia, por isso sempre precisamos testar atual. Se não tem mais dados para percorrer, passamos o array que montamos para resolve e a interação termina.

Isso é desse jeito porque a obtenção de um dado de um store é uma operação assíncrona, ou seja, enquanto você esta obtendo os dados do IndexedDB sua aplicação não trava.

Sucesso e bom estudo meu aluno.

Caro magnissonante Flávio, creio ter compreendido com sua explicação, então em síntese o atual.continue() funciona como uma função recursiva sempre chamando o callback de onsuccess, desde que este não seja undefined claro.

Obrigado e espero te ver num módulo IV deste mesmo curso em breve :)

Hehe! O termo "recursivo" matou a charada. É isso mesmo! Eu também espero um módulo IV :) Deixa acumular novidades este ano, com o ES2017!

Sucesso e bom estudo!