Async: Promesa de apoyo

Creado en 13 nov. 2015  ·  22Comentarios  ·  Fuente: caolan/async

Agregue soporte de promesa para permitir mezclar diferentes tareas:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err) => {
    if (err) {
        console.error(err);
    }
});
feature

Comentario más útil

Creo que al igual que hay async.asyncify, podría haber una función async.promisify.

Entonces puedo esperar async.promisify (async.mapLimit (x, 10, mapper))

Todos 22 comentarios

asyncify tomará una función sincrónica que devuelve una Promesa y llamará a una devolución de llamada en sus controladores resueltos / rechazados:

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async.asyncify(function(content) {
        // Do something and return Promise
        return mongoose.models.file.create({
            name: filepath,
            content: content
        });
    })
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Pero esa característica no está documentada ...

También tuve otro pensamiento: ¿deberíamos asincificar automáticamente las funciones que devuelven promesas (o manejarlas adecuadamente?). ¿Qué debe hacer async cuando se le pasa una función ES-cualquiera async (que devuelve implícitamente una promesa)?

p.ej

async.waterfall([
    function (done) {
        // Do something and call done()
        fs.readFile(filepath, done);
    },
    async function(content) {
        return await mongoose.models.file.create({
            name: filepath,
            content: content
        });
    }
], (err, model) => {
    if (err) {
        console.error(err);
    }
});

Personalmente, creo que async debería asincificar las promesas de forma predeterminada. Hay algunas funciones asíncronas que escribo que también tengo que alimentar en async.queue, pero no quiero escribir esto:

import {queue, asyncify} from 'async'

const run = asyncify(async function () {
  await someStuff()
})

const q = async.queue(run)
q.push('asdf')

donde podría estar escribiendo esto

import {queue} from 'async'

async function run () {
  await someStuff()
}

const q = async.queue(run)
q.push('asdf')

Se agregaron los documentos por asyncify . Voy a mantener esto abierto para el comportamiento de asincronización automática.

Sobre esto, estaba experimentando con el mismo código base y usando una interfaz Promise para métodos que usan callback como último parámetro. ¡Compruébalo !

async.waterfall([
  function (callback) {
    callback(null, 'one', 'two')
  },
  function (arg1, arg2, callback) {
    // arg1 now equals 'one' and arg2 now equals 'two'
    callback(null, 'three')
  },
  function (arg1, callback) {
    // arg1 now equals 'three'
    callback(null, 'done')
  }
]).then(function (value) {
  console.log(value === 'done')
})

¿Qué piensa usted al respecto? Creo que podría ser fácil adaptar la biblioteca. Vea, por ejemplo, cómo funciona la biblioteca con el control cb y promise .

Muy interesante. Si Async manejó correctamente las funciones que devuelven promesas, entonces también podría aceptar funciones Async promisificadas con bastante facilidad. Esto funcionaría:

async.parallel([
  async.waterfall([
    asyncFn1,
    function (result1, next) {
      //...
    }
    asyncFn2,
    //...
  ]), // no callback!
  async.each(arr, function (item, cb) {
    //...
  })
  otherAsyncFn
], done)

Sería mucho más fácil combinar funciones Async.

El problema actual es que las devoluciones de llamada son opcionales. Dejar el último argumento aún ejecuta la tarea. Me encantaría hacer esto para que las funciones Async se cursen automáticamente; si dejas la devolución de llamada, se aplica parcialmente la función y todo lo que necesitas hacer es llamarla con una devolución de llamada. Pero dado que muchos métodos tienen parámetros opcionales, y nos estamos moviendo hacia devoluciones de llamada opcionales en todos los ámbitos, realmente no puede hacerlo. Nuestros métodos son variados y no se pueden utilizar funciones variadas.

Sin embargo, si dejar la devolución de llamada final de un método hace que devuelva una Promesa, y si Async está configurado para manejar funciones que devuelven promesas, es una combinación interesante. Un problema importante es que Async tendría que integrarse con una biblioteca de promesas, ¿cuál? ¿Dependemos de global.Promise , lo que obliga a los motores más antiguos a realizar un polyfill, o usamos algo como Bluebird? Además, Async es una especie de declaración contra las promesas: funciones de orden superior para funciones de aceptación de devolución de llamada, en lugar de adoptar el paradigma Futures. Estoy a favor de la interoperabilidad con Promises, pero creo que tener promesas de devolución Async está un poco fuera de su filosofía de diseño.

@ temprano

Siento que Promises es un flujo de trabajo alineado con las últimas versiones de nodo (> = 4). En estas versiones, las promesas están disponibles, por lo que mi visión es usar el flujo de trabajo de promesas cuando el entorno global tiene promesas.

Es posible agregar un polyfill pequeño (verifique la promesa del meñique ) pero en mi opinión no tiene sentido proporcionar un polyfill. Es mejor forzar al usuario a actualizar la versión del nodo para usar las funciones del último nodo. De verdad, verifique (obtuvo 6 PR) [https://github.com/sindresorhus/got/pull/140]. Las dependencias no son bienvenidas en proyectos muy pequeños y se utilizan en todas partes.

Quizás sea bueno incluir esta característica después de la modularización asincrónica, para que el código base sea más fácil de adaptar.

¡Pero definitivamente, alinear async con promesas es totalmente _debe_!

@Kikobeats : +1:

Las promesas se están convirtiendo en las funciones asíncronas de primera clase. Por lo tanto, es difícil imaginar la biblioteca imprescindible para la asincronía sin el soporte completo de ellos.

Creo que podría implementarse sin polyfill pero con detección de características: permitir si hay un objeto Promise global con el método resolve .

@aearly bluebird agrega compatibilidad con el navegador a la lista de su polyfilling. Creo que podría ser apropiado usarlo.

@martinheidegger Bluebird es demasiado grande para esto. Lanzará 76 Kb (minificado) para soporte simple de métodos de promesa.

Nuevamente, usar la interfaz de devolución de llamada o promesas en su flujo de trabajo de backend es un proceso natural basado en la versión de su nodo.

  • Si tiene un backend de más tiempo (2 años o más, tal vez), usa la versión 0.10 o 0.12 , por lo que su código está escrito en estilo callback.
  • Si el backend tiene menos de ~ 6 meses y usa la versión >=4 node, probablemente use un estilo Promise.

Pero en cualquier caso no tienes un estilo mixto.

Por lo tanto, no es necesario agregar una dependencia para el soporte de Promesas; Si async admite promesas algún día en el futuro, puede usarlo si la versión de su nodo admite Promises.

Caso extremo: _Estoy usando una versión de nodo anterior pero mi backend está escrito usando promesas style_. Luego, ha definido un objeto Promises como global o ha definido uno antes de usar async . Lo que quieras. Simplemente.

Mismo comportamiento para el lado de la interfaz. No es necesaria la dependencia.

Mmmm, parece que se siguen aplicando los mismos problemas que tenía Promises hace 4 o 5 años. Si todos estuvieran usando el nodo 4 o posterior, y navegadores modernos con soporte ES6, podríamos utilizar fácilmente las promesas internamente donde corresponda.

El problema es que dejamos nuestro nodo 0.12 y los usuarios de navegadores más antiguos en el polvo, lo que les obliga a realizar un polyfill. ¿Qué polyfill utilizan? No quisiéramos agrupar uno, incluso la promesa del meñique tiene peso. Además, las personas que usan promesas fuera del estándar ES6 Promise querrán usar bluebird oq, etc., sea lo que sea que estén usando. No quiero requerir el uso de un polyfill - npm i -S async debería ser todo lo que la gente debe hacer.

Async también ha sido una reacción en contra de Promises, una forma alternativa de administrar código asincrónico. Empezar a usar Promises parece un paso atrás. Las devoluciones de llamada administradas correctamente pueden ser tan poderosas como las promesas (y en muchos casos, más rápidas, ya que las promesas tienen un aplazamiento de bucle de eventos incorporado).

Estoy a favor de la interoperabilidad con promesas, si una función recibe una Promesa u otra "entonces habilitada", definitivamente deberíamos aprovecharla. Pero creo que deberíamos evitar crear y / o devolver Promesas internamente, solo por el hecho de que el soporte de ES6 en todas las plataformas aún tiene un camino por recorrer.

De acuerdo, las promesas no son baratas de crear o procesar. Prefiero ver algo como esto como una extensión opcional. Las promesas son geniales pero no siempre las querrás

En mi humilde opinión, después de migrar una gran cantidad de código de nodo a promesas + co + rendimiento, no encontré un reemplazo directo solo para .eachLimit() . Probablemente, la lista de casos útiles es mucho menor de lo que parece a primera vista y se puede manejar con un paquete separado.

Me gusta la pequeña extensión de @Kikobeats , puede tener sentido recomendarla en el archivo Léame (/ cc @aearly).

Estaría fuertemente en contra del apoyo oficial de las promesas en async por razones expuestas por mí y otros usuarios.

@megawac ¿Qué pasa con el caso en el que una función devuelve una promesa? por ejemplo, el ejemplo de @SEAPUNK .

@megawac I promise-async . Entonces, si alguien quiere usar Promise, creo que está listo: +1:

@aearly , eso estaría bien, supongo (entonces =) pero prefiero dejarlo en el complemento
tierra personalmente

El viernes 22 de enero de 2016 a las 2:17 p.m., Kiko Beats [email protected]
escribió:

@megawac https://github.com/megawac Agregué soporte para el estilo de devolución de llamada
y pruebas para promise-async
https://github.com/Kikobeats/promise-async#promise -async. Entonces sí
si alguien quiere usar Promise, creo que está listo [imagen:: +1:]

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/caolan/async/issues/956#issuecomment -174016628.

Aquí hay otro paquete que promete todos los métodos asincrónicos disponibles:
https://github.com/eladnava/koa-async

Creo que al igual que hay async.asyncify, podría haber una función async.promisify.

Entonces puedo esperar async.promisify (async.mapLimit (x, 10, mapper))

No me opondría a eso si desea crear una solicitud de extracción

El sábado 17 de diciembre de 2016 a las 4:57 p.m., Manoj Patel [email protected]
escribió:

Creo que al igual que hay async.asyncify, podría haber una async.promisify
función.

Entonces puedo esperar async.promisify (async.mapLimit (x, 10, mapper))

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

Estoy usando el método promisifyAll del módulo bluebird para convertir las devoluciones de llamada en promesas para que los métodos de async se conviertan en:

// adds '<original-method>Async' to class 
Promise.promisifyAll(async);

function somePromise() {
    return async.parallelAsync([
        function(cb) {
            setTimeout(function(){
                cb(new Error('err'), 'foo')
            }, 1000);
        },
        function(cb) {
            setTimeout(function(){
                cb(null, 'bar')
            }, 1000);
        }
    ]);
}

somePromise().then(function(result){
    console.log('result',result);
}).catch(function(err){
    console.log('err',err);
});

Ejemplo de JSFiddle

¿Fue útil esta página
0 / 5 - 0 calificaciones