<p>async.mapLimit não retorna uma promessa</p>

Criado em 27 ago. 2019  ·  14Comentários  ·  Fonte: caolan/async

Qual versão do assíncrono você está usando?
3.1.0

Em qual ambiente o problema ocorreu (versão do nó / versão do navegador)
nó 12.9.1, npm 6.10.2, navegador N / A

O que você fez?
O problema tem um thread no stackoverflow
https://stackoverflow.com/questions/57622495/async-maplimit-with-promise/57659221#57659221

Basicamente, tenho este código:

async = require('async');
let numPromise = async.mapLimit(['1','2','3','4','5'], 3, function(num, callback){
    setTimeout(function(){
        num = num * 2,
        console.log(num);
        callback(null, num);
    }, 
    2000);
})
numPromise
.then((result) => console.log("success:" + result))
.catch(() => console.log("no success"));

O que você esperava que fosse acontecer?
Execute sem erros, 'numPromise' deve conter uma promessa. o console deve registrar '2,4,6,8,10' e ' sucesso: 2 , 4,6,8,10'

Qual foi o resultado real?
Ele lança um erro: TypeError: Não é possível ler a propriedade 'then' de undefined

Observação: quando eu uso o módulo 'promessa async' em vez de 'async', esse código funciona bem. A documentação diz que async.mapLimit (e outros) retornam uma Promise quando nenhum retorno de chamada é fornecido, mas fico indefinido. Não foi possível encontrar nenhuma amostra de trabalho ainda (por favor, veja também minha sugestão sobre o problema 'precisamos de amostras').

bug

Comentários muito úteis

const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
//    await delay(200);
//    return num*2;
// })
numPromise.then(console.log)

Todos 14 comentários

const async = require('async');
const delay = require('util').promisify(setTimeout);
const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
// or const numPromise = async.mapLimit(['1','2','3','4','5'], 3, async num => {
//    await delay(200);
//    return num*2;
// })
numPromise.then(console.log)

Muito obrigado, exemplo razoável. Infelizmente, me dá "SyntaxError: await só é válido na função assíncrona" (para 'await async.mapLimit')
Mais alguma coisa que devo considerar?

A mensagem de erro diz tudo, await só é válido em uma função assíncrona, até que a proposta de nível superior await seja implementada

Sim, estava procurando um exemplo totalmente funcional, pois esta é realmente a parte com a qual eu lutei. Não importa, finalmente comecei a funcionar:

const myAsyncFunction = async function(){
    //const numPromise = await async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2))
    const numPromise = await async.mapLimit(['1','2','3','4','5'], 3, async num => {
        await delay(2000);
        console.log(num*2);
        return num*2;
     })
    //numPromise.then(console.log)
    return numPromise;
}
myAsyncFunction()
.then((result) => console.log(result));

Ainda não tenho certeza do que é diferente das tentativas anteriores, mas validarei e adicionarei mais algumas conclusões sobre isso.
Em qualquer caso, meu ponto é que tudo isso não é totalmente intuitivo, eu acredito, então exemplos como este podem ajudar!
E ... eu ainda não entendo completamente por que precisamos envolver todos os async / awaits em torno dele, quando async.mapLimit deveria apenas retornar uma promessa simples por si só ...

opa esqueci um await no meu código anterior, editado

Tudo bem, agora eu confirmo totalmente :-) Então, provavelmente o principal problema era que a função iteratee não era totalmente assíncrona?
De qualquer forma, isso funciona como um encanto ao que parece e provavelmente é um ótimo exemplo também! Obrigado por continuar nisso comigo !!

Consulte https://github.com/caolan/async/issues/1673 para

async.mapLimit(['1','2','3','4','5'], 3, async num => delay(200).then(() => num*2)) // works

async.mapLimit(['1','2','3','4','5'], 3, num => delay(200).then(() => num*2)) // doesn't work

Promise.all(['1','2','3','4','5'].map(num => delay(200).then(() => num*2))) // works (plain promises)

Eu vejo, você está completamente comigo, ou seja, teve os mesmos problemas.
Acho que meu ponto principal é realmente o seguinte - a documentação apenas afirma "Retorna: uma promessa se nenhum retorno de chamada for passado" - então, quando eu tenho a variante de retorno de chamada e simplesmente a deixo de fora, como posso pensar que preciso para adicionar a palavra-chave 'async' quando funcionou sem isso na versão de retorno de chamada. Além disso, usando o módulo 'promessa assíncrona', ele funciona exatamente como eu esperava.

Além disso, ainda não entendi por que o exemplo 'Promise.all' acima funciona ... isso é realmente confuso para mim.

A função iteratária sendo async ou usando um retorno de chamada não deve afetar o retorno de uma promessa se o retorno de chamada final for omitido. Este é um bug.

Aposto que isso está relacionado a # 1685

Aposto que isso está relacionado a # 1685

Eu definitivamente me lembro de ter tido esse problema antes em alguma versão dos meus exemplos de código também. Presumi que obviamente foi causado por algum código errado. Então, é interessante ver que ele aparece em um sabor diferente também.

Eu pesquisei mais sobre isso.

mapLimit está funcionando conforme o esperado. Eu apostaria que todos os problemas que as pessoas veem aqui são devido às limitações de detecção de funções de retorno de promessa ou compiladores (por exemplo, babel, typescript) que não preservam funções async .

Eu pesquisei mais sobre isso.

mapLimit está funcionando conforme o esperado. Eu apostaria que todos os problemas que as pessoas veem aqui são devido às limitações de detecção de funções de retorno de promessa ou compiladores (por exemplo, babel, typescript) que não preservam funções async .

Qual é a melhor maneira de lidar com esses cenários em que async não é preservado nas compilações?

Envolva a função async em asyncify . http://caolan.github.io/async/v3/global.html#AsyncFunction

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