Saltar al contenido

Diferencia entre async/await y ES6 yield con generadores

Puede que se de el caso de que encuentres alguna incompatibilidad con tu código o proyecto, recuerda probar siempre en un entorno de testing antes aplicar el código al trabajo final.

Solución:

Pues resulta que hay una relación muy estrecha entre async/await y generadores. Y yo creo async/await siempre se basará en generadores. Si miras la forma en que transpila Babel async/await:

Babel toma esto:

this.it('is a test', async function () 

    const foo = await 3;
    const bar = await new Promise(resolve => resolve('7'));
    const baz = bar * foo;
    console.log(baz);

);

y lo convierte en esto

function _asyncToGenerator(fn) 
    return function () 
        var gen = fn.apply(this, arguments);
        return new Promise(function (resolve, reject) 
            function step(key, arg) 
                try 
                    var info = gen[key](arg);
                    var value = info.value;
                 catch (error) 
                    reject(error);
                    return;
                
                if (info.done) 
                    resolve(value);
                 else 
                    return Promise.resolve(value).then(function (value) 
                        return step("next", value);
                    , function (err) 
                        return step("throw", err);
                    );
                
            

            return step("next");
        );
    ;



this.it('is a test', _asyncToGenerator(function* ()    // << now it's a generator

    const foo = yield 3;    //  <<< now it's yield, not await
    const bar = yield new Promise(resolve => resolve(7));
    const baz = bar * foo;
    console.log(baz);

));

tú haces los cálculos.

Esto hace que parezca el async palabra clave es solo esa función contenedora, pero si ese es el caso, entonces await simplemente se convierte en yield, probablemente habrá un poco más en la imagen más adelante cuando se vuelvan nativos.

Puede ver más de una explicación para esto aquí: https://www.promisejs.org/generators/

yield puede ser considerado como el bloque de construcción de await. yield toma el valor que se le da y lo pasa a la persona que llama. La persona que llama puede hacer lo que quiera con ese valor (1). Más tarde, la persona que llama puede devolver un valor al generador (a través de generator.next()) que se convierte en el resultado de la yield expresión (2), o un error que parecerá ser arrojado por el yield expresión (3).

asyncawait se puede considerar usar yield. En (1) la persona que llama (es decir, el asyncawait controlador – similar a la función que publicaste) envolverá el valor en una promesa usando un algoritmo similar a new Promise(r => r(value) (Nota, noPromise.resolve, pero eso no es gran cosa). A continuación, espera a que se resuelva la promesa. Si cumple, vuelve a pasar el valor cumplido en (2). Si lo rechaza arroja el motivo del rechazo como error en (3).

Entonces la utilidad de asyncawait es esta maquinaria la que utiliza yield para desenvolver el valor producido como una promesa y devolver su valor resuelto, repitiendo hasta que la función devuelva su valor final.

¿Qué diablos es la diferencia entre el await palabra clave y la yield ¿palabra clave?

El await la palabra clave solo debe usarse en async functions, mientras que el yield la palabra clave solo se debe usar en el generador function*s. Y obviamente también son diferentes: uno devuelve promesas, el otro devuelve generadores.

Lo hace await siempre convertir algo en una promesa, mientras que yield no ofrece tal garantía?

Sí, await llamará Promise.resolve sobre el valor esperado.

yield solo produce el valor fuera del generador.

Te mostramos las comentarios y valoraciones de los lectores

Puedes añadir valor a nuestro contenido asistiendo con tu experiencia en los comentarios.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *