<p>async.mapLimit ne renvoie pas de promesse</p>

Créé le 27 août 2019  ·  14Commentaires  ·  Source: caolan/async

Quelle version d'async utilises-tu ?
3.1.0

Dans quel environnement le problème s'est-il produit (version du nœud/version du navigateur)
nœud 12.9.1, npm 6.10.2, navigateur N/A

Qu'est-ce que tu as fait?
Le problème a un thread dans stackoverflow
https://stackoverflow.com/questions/57622495/async-maplimit-with-promise/57659221#57659221

En gros, j'ai ce code :

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

Que vous attendiez-vous à ce qu'il se passe ?
Exécutez sans erreur, 'numPromise' doit contenir une promesse. la console devrait enregistrer '2,4,6,8,10' et ' success:2 ,4,6,8,10'

Quel a été le résultat réel ?
Il renvoie une erreur : TypeError : Impossible de lire la propriété 'alors' d' undefined

Remarque : lorsque j'utilise le module 'promise-async' au lieu de 'async', ce code fonctionne bien. La documentation indique qu'async.mapLimit (et d'autres) renvoient une promesse lorsqu'aucun rappel n'est fourni, mais je ne suis pas défini. Je n'ai pas encore trouvé d'échantillon fonctionnel (veuillez également consulter ma suggestion sur le problème « besoin d'échantillons »).

bug

Commentaire le plus utile

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)

Tous les 14 commentaires

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)

Merci beaucoup, exemple raisonnable. Malheureusement, me donne "SyntaxError: wait n'est valide que dans la fonction async" (pour 'wait async.mapLimit')
Autre chose que je dois considérer ?

Le message d'erreur dit tout, wait n'est valide que dans une fonction asynchrone, jusqu'à ce que la proposition d'attente de niveau supérieur soit implémentée

Oui, je cherchais un exemple pleinement fonctionnel, car c'est vraiment la partie avec laquelle j'ai eu du mal. Peu importe, je l'ai enfin mis en service :

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

Je ne suis pas encore vraiment sûr de ce qui est différent des essais précédents, mais je validerai et ajouterai des conclusions supplémentaires à ce sujet.
Dans tous les cas, ce que je veux dire, c'est que tout cela n'est pas entièrement intuitif, je crois, donc des exemples comme celui-ci peuvent aider !
Et... je ne comprends toujours pas tout à fait pourquoi nous devons envelopper tous les async/attends autour, alors que async.mapLimit devrait simplement renvoyer une promesse simple par lui-même...

oups j'ai oublié un wait dans mon code précédent, édité

D'accord, maintenant je confirme pleinement :-) Donc, le problème principal était probablement que la fonction iteratee n'était pas entièrement asynchrone ?
Quoi qu'il en soit, cela fonctionne à merveille, semble-t-il, et c'est probablement aussi un excellent exemple ! Merci de rester avec moi !!

Voir https://github.com/caolan/async/issues/1673 pour savoir pourquoi

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)

Je vois, vous êtes complètement avec moi, c'est-à-dire avez eu les mêmes problèmes.
Je suppose que mon point principal est vraiment le suivant - la documentation indique simplement "Retours: une promesse si aucun rappel n'est passé" - donc, quand j'ai la variante de rappel, et que je laisse simplement cela de côté, comment pourrais-je penser que j'ai besoin pour ajouter le mot-clé 'async' quand cela fonctionnait sans cela dans la version de rappel. De plus, en utilisant le module 'promise-async', cela fonctionne exactement comme je m'y attendais.

De plus, je n'ai pas encore compris pourquoi l'exemple 'Promise.all' ci-dessus fonctionne... c'est vraiment déroutant pour moi.

La fonction iteratee étant async ou utilisant un rappel ne devrait pas affecter le retour d'une promesse si le rappel final est omis. C'est un bogue.

Je vous parie que c'est lié à #1685

Je vous parie que c'est lié à #1685

Je me souviens certainement d'avoir déjà eu ce problème dans certaines versions de mes exemples de code. J'ai supposé évidemment que cela était causé par un mauvais codage. Donc, intéressant de voir qu'il apparaît également dans une saveur différente.

J'ai examiné cela plus en détail.

mapLimit fonctionne comme prévu. Je parierais que tous les problèmes que les gens voient ici sont dus aux limitations de la détection des fonctions de retour de promesse, ou aux compilateurs (par exemple babel, tapuscrit) ne préservant pas les fonctions async .

J'ai examiné cela plus en détail.

mapLimit fonctionne comme prévu. Je parierais que tous les problèmes que les gens voient ici sont dus aux limitations de la détection des fonctions de retour de promesse, ou aux compilateurs (par exemple babel, tapuscrit) ne préservant pas les fonctions async .

Quelle est la meilleure façon de gérer de tels scénarios où async n'est pas conservé sur les compilations ?

Enveloppez la fonction async dans asyncify . http://caolan.github.io/async/v3/global.html#AsyncFunction

Cette page vous a été utile?
0 / 5 - 0 notes