Async: Promessa de suporte

Criado em 13 nov. 2015  ·  22Comentários  ·  Fonte: caolan/async

Adicione suporte de promessa para permitir a combinação de tarefas diferentes:

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

Comentários muito úteis

Acho que, assim como há async.asyncify, pode haver uma função async.promisify.

Então, posso apenas aguardar async.promisify (async.mapLimit (x, 10, mapper))

Todos 22 comentários

asyncify assumirá uma função síncrona que retorna uma promessa e chamará um retorno de chamada em seus manipuladores resolvidos / rejeitados:

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);
    }
});

Mas esse recurso não está documentado ...

Eu também pensei: devemos asyncificar automaticamente as funções que retornam promessas (ou tratá-las apropriadamente?). O que o assíncrono deve fazer ao passar uma função ES-qualquer async (que implicitamente retorna uma promessa)?

por exemplo

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);
    }
});

Pessoalmente, acho que async deve asyncify promessas por padrão. Existem algumas funções assíncronas que escrevo que também devo alimentar em async.queue, mas não quero escrever isto:

import {queue, asyncify} from 'async'

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

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

onde eu poderia estar escrevendo isso

import {queue} from 'async'

async function run () {
  await someStuff()
}

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

Adicionados os documentos para asyncify . Vou manter isso aberto para o comportamento de asyncify-ing automático.

Sobre isso, eu estava experimentando usar a mesma base de código e usar uma interface Promise para métodos que usam callback como último parâmetro. verifique !

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')
})

o que você acha disso? Acho que seria fácil adaptar a biblioteca. Veja, por exemplo, como funciona o identificador de biblioteca cb e promessa .

Muito interessante. Se o Async manipulasse corretamente as funções que retornam promessas, ele também poderia aceitar funções Async prometidas com bastante facilidade. Isso funcionaria:

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

Seria muito mais fácil combinar funções Async.

O problema hoje é que os retornos de chamada são opcionais. Deixar de fora o último argumento ainda executa a tarefa. Eu adoraria fazer isso, as funções assíncronas são ativadas automaticamente - se você deixar o retorno de chamada, ele aplicará a função parcialmente e tudo o que você precisa fazer é chamá-lo com um retorno de chamada. Mas, visto que muitos métodos têm parâmetros opcionais e estamos avançando em direção a retornos de chamada opcionais em toda a linha, você não pode realmente fazer isso. Nossos métodos são variáveis, e você não pode curry funções variadic.

No entanto, se deixar de fora o retorno de chamada final de um método, ele retornará uma promessa e se Async estiver configurado para lidar com funções que retornam promessas, é uma combinação interessante. Um grande problema é que o Async teria que ser integrado a uma biblioteca de promessas - qual? Dependemos de global.Promise , forçando os motores mais antigos a polyfill, ou usamos algo como o Bluebird? Além disso, Async é uma espécie de declaração contra promessas - funções de ordem superior para funções de aceitação de retorno de chamada, em vez de adotar o paradigma Futures. Sou totalmente a favor da interoperabilidade com o Promises, mas acho que o Async retorna promessas está um pouco fora de sua filosofia de design.

@aearly

Eu sinto que o Promises é um fluxo de trabalho alinhado com as últimas versões do nó (> = 4). Nessas versões estão disponíveis Promises, portanto, minha visão é usar o workflow de Promise quando o ambiente global tiver Promises.

É possível adicionar um polyfill minúsculo (verifique a promessa do dedinho ), mas na minha opinião não faz sentido fornecer um polyfill. Melhor forçar o usuário a atualizar a versão do nó para usar os recursos do último nó. Realmente, verifique (tenho 6 PR) [https://github.com/sindresorhus/got/pull/140]. Dependências não são bem-vindas em projetos muito pequenos e são usadas em qualquer lugar.

Talvez seja bom incluir esse recurso após a modularização assíncrona, para que a base de código seja mais fácil de se adaptar.

Mas, definitivamente, alinhar assíncrono com promessas é totalmente _deve_!

@Kikobeats : +1:

As promessas estão se tornando as funções assíncronas de primeira classe. Portanto, é difícil imaginar a biblioteca obrigatória para assincronia sem o suporte total deles.

Acho que poderia ser implementado sem polyfill, mas com detecção de recurso: permitir se houver um objeto Promise global com o método resolve .

@aearly bluebird adiciona compatibilidade de navegador à lista de polyfilling. Acho que pode ser apropriado usá-lo.

@martinheidegger Bluebird é grande demais para isso. Ele lançará 76 Kb (reduzido) para suporte simples de métodos de promessa.

Novamente, usar callback ou promises interface em seu fluxo de trabalho de back-end é um processo natural baseado em sua versão de nó.

  • Se você tiver um back-end de mais tempo (2 anos ou mais, talvez), use a versão 0.10 ou 0.12 , portanto, seu código é escrito no estilo de retorno de chamada.
  • Se o seu backend tem menos de ~ 6 meses e você usa a versão >=4 node, provavelmente você usa um estilo Promise.

Mas em qualquer caso, você não tem um estilo misto.

Portanto, não é necessário adicionar uma dependência para o suporte Promises; Se o async oferecer suporte a promessas um dia no futuro, você poderá usá-lo se sua versão do nó oferecer suporte a promessas.

Caso extremo: _Estou usando uma versão de nó mais antiga, mas meu back-end foi escrito usando o estilo de promessas_. Então, você definiu um objeto Promises como global ou definiu um antes de usar async . O que você quiser. Simplesmente.

Mesmo comportamento para o lado do frontend. Não é necessária dependência.

Hmmn, parece que os mesmos problemas que as Promessas tinham de 4 a 5 anos atrás ainda se aplicam. Se todos estivessem usando o nó 4 ou posterior, e navegadores modernos com suporte ES6, poderíamos facilmente utilizar as promessas internamente quando aplicável.

O problema é que deixamos nosso nó 0.12 e os usuários de navegadores mais antigos comendo poeira, exigindo que eles façam o polyfill. Qual polyfill eles usam? Não gostaríamos de empacotar um, mesmo a promessa do dedinho tem peso para isso. Além disso, as pessoas que estão usando promessas fora do padrão ES6 Promise vão querer usar bluebird ou q etc., o que quer que estejam usando. Não quero exigir o uso de um polyfill - npm i -S async deve ser tudo o que as pessoas precisam fazer.

Async também tem sido uma espécie de reação contra Promises - uma forma alternativa de gerenciar código assíncrono. Começar a usar o Promises parece um retrocesso. Retornos de chamada gerenciados adequadamente podem ser tão poderosos quanto promessas (e, em muitos casos, mais rápidos, já que o Promises tem um adiamento de loop de evento integrado).

Eu sou totalmente a favor da interoperabilidade com promessas, se uma função for aprovada como uma promessa ou outro "impossível", então devemos definitivamente tirar vantagem disso. Mas acho que devemos evitar criar e / ou retornar Promises internamente, apenas devido ao fato de que o suporte ES6 entre plataformas ainda tem um longo caminho a percorrer.

Concordo, as promessas não são baratas de criar ou processar. Prefiro ver algo assim como uma extensão opcional. As promessas são ótimas, mas você nem sempre as quer

IMHO, depois de migrar muito código do nó para promessas + co + rendimento, não encontrei substituição direta apenas para .eachLimit() . Provavelmente, a lista de casos úteis é muito menor do que parece à primeira vista e pode ser tratada com um pacote separado.

Eu gosto da pequena extensão de @Kikobeats , pode fazer sentido recomendá-la no readme (/ cc @aearly).

Eu seria fortemente contra o suporte oficial de promessas no assíncrono por motivos apresentados por mim e por outros usuários.

@megawac E o caso em que uma função retorna uma promessa? por exemplo, o exemplo de @SEAPUNK .

@megawac I Adicionado suporte para estilo de retorno de chamada, testes e construção de navegador em promessa assíncrona . Então, se alguém quiser usar o Promise, acho que está pronto: +1:

@aearly ,
terra pessoalmente

Na sexta-feira, 22 de janeiro de 2016 às 14h17, Kiko Beats [email protected]
escreveu:

@megawac https://github.com/megawac Eu adicionei suporte para estilo de retorno de chamada
e testes para promessa assíncrona
https://github.com/Kikobeats/promise-async#promise -async. Então se
alguém quiser usar Promise, acho que está pronto [imagem:: +1:]

-
Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/caolan/async/issues/956#issuecomment -174016628.

Aqui está outro pacote que promete todos os métodos assíncronos disponíveis:
https://github.com/eladnava/koa-async

Acho que, assim como há async.asyncify, pode haver uma função async.promisify.

Então, posso apenas aguardar async.promisify (async.mapLimit (x, 10, mapper))

Eu não faria objeções a isso se você quiser criar uma solicitação de pull

No sábado, 17 de dezembro de 2016 às 4:57 PM, Manoj Patel [email protected]
escreveu:

Acho que, assim como há async.asyncify, pode haver um async.promisify
função.

Então, posso apenas aguardar async.promisify (async.mapLimit (x, 10, mapper))

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

Estou usando o método promisifyAll de bluebird module para converter retornos de chamada em promessas para que os métodos assíncronos se tornem:

// 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);
});

Exemplo JSFiddle

Esta página foi útil?
0 / 5 - 0 avaliações