Iteradores assíncronos JavaScript

Resumo : neste tutorial, você aprenderá sobre os iteradores assíncronos JavaScript que permitem acessar dados assíncronos sequencialmente.

Introdução aos iteradores assíncronos JavaScript

ES6 introduziu a interface do iterador que permite acessar dados sequencialmente. O iterador é adequado para acessar fontes de dados síncronas, como arrays , sets e maps .

O método principal de uma interface iteradora é aquele next()que retorna o {value, done}objeto, onde doneé um booleano que indica se o final da sequência foi atingido e valueé o valor produzido na sequência.

Os dados síncronos significam que o próximo valuena sequência e o doneestado são conhecidos no momento em que o next()método retorna.

Além das fontes de dados síncronas, o JavaScript geralmente precisa acessar fontes de dados assíncronas, como acesso de E/S. Para fontes de dados assíncronas, o estado valuee donedo iterador geralmente é desconhecido no momento em que o next()método retorna.

Para lidar com as fontes de dados assíncronas, ES2018 introduziu a interface do iterador assíncrono (ou iterador assíncrono).

Um iterador assíncrono é como um iterador, exceto que seu next()método retorna uma promessa que é resolvida para o {value, done}objeto.

A seguir ilustra a Sequenceclasse que implementa a interface do iterador. (Confira o tutorial do iterador para obter mais informações sobre como implementar Sequencea classe.)

class Sequence {
    constructor(start = 0, end = Infinity, interval = 1) {
            this.start = start;
            this.end = end;
            this.interval = interval;
        }
        [Symbol.iterator]() {
            let counter = 0;
            let nextIndex = this.start;
            return {
                next: () => {
                    if (nextIndex <= this.end) {
                        let result = {
                            value: nextIndex,
                            done: false
                        }
                        nextIndex += this.interval;
                        counter++;
                        return result;
                    }
                    return {
                        value: counter,
                        done: true
                    };
                }
            }
        }
}Linguagem de código:  JavaScript  ( javascript )

Para tornar esta Sequenceclasse assíncrona, você precisa modificá-la da seguinte forma:

  • Use o Symbol.asyncIteratorem vez doSymbol.iterator
  • Retorne uma promessa do next()método.

O código a seguir transforma a Sequenceclasse em AsyncSequenceclasse:

class AsyncSequence {
    constructor(start = 0, end = Infinity, interval = 1) {
            this.start = start;
            this.end = end;
            this.interval = interval;
        }
        [Symbol.asyncIterator]() {
            let counter = 0;
            let nextIndex = this.start;
            return {
                next: async () => {
                    if (nextIndex <= this.end) {
                        let result = {
                            value: nextIndex,
                            done: false
                        }
                        nextIndex += this.interval;
                        counter++;

                        return new Promise((resolve, reject) => {
                            setTimeout(() => {
                                resolve(result);
                            }, 1000);
                        });
                    }
                    return new Promise((resolve, reject) => {
                        setTimeout(() => {
                            resolve({
                                value: counter,
                                done: true
                            });
                        }, 1000);

                    });
                }
            }
        }
}Linguagem de código:  JavaScript  ( javascript )

O AsyncSequenceretorna o próximo número na sequência a cada 1 segundo.

A for await...ofdeclaração

Para iterar sobre um objeto iterável assíncrono, ES2018 introduziu a for await...ofinstrução:

for await (variable of iterable) {
    // statement
}
Linguagem de código:  JavaScript  ( javascript )

Como podemos usar a awaitpalavra-chave apenas em uma asyncfunção, podemos criar um IIFE assíncrono , pois usa a AsyncSequenceclasse da seguinte maneira:

(async () => {

    let seq = new AsyncSequence(1, 10, 1);

    for await (let value of seq) {
        console.log(value);
    }

})();
Linguagem de código:  JavaScript  ( javascript )

Saída (cada número é retornado a cada segundo)

1
2
3
4
5
6
7
8
9
10Linguagem de código:  JavaScript  ( javascript )

A tabela a seguir ilustra as diferenças entre os iteradores e os iteradores assíncronos:

# Iteradores Iteradores assíncronos
Símbolo bem conhecido Symbol.iterator Symbol.asyncIterator
next() o valor de retorno é {value, done } Promiseque resolve{value, done}
Instrução de loop for...of for await...of

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *