Async: Promesse de soutien

Créé le 13 nov. 2015  ·  22Commentaires  ·  Source: caolan/async

Ajout de la prise en charge des promesses pour permettre de mélanger différentes tâches :

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

Commentaire le plus utile

Je pense que tout comme il y a async.asyncify, il pourrait y avoir une fonction async.promisify.

Ensuite, je peux juste attendre async.promisify(async.mapLimit(x,10, mapper))

Tous les 22 commentaires

asyncify prendra une fonction synchrone qui renvoie une promesse et appellera un rappel sur ses gestionnaires résolus/rejetés :

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

Mais cette fonctionnalité n'est pas documentée...

J'ai également eu une autre idée : devrions-nous asynchrone automatiquement les fonctions qui renvoient des promesses (ou les gérer de manière appropriée ?). Que doit faire async lorsqu'une fonction ES-whatever async transmise (qui renvoie implicitement une promesse) ?

par exemple

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

Personnellement, je pense qu'async devrait asynchrone les promesses par défaut. Il y a quelques fonctions asynchrones que j'écris que je dois également alimenter dans async.queue, mais je ne veux pas écrire ceci :

import {queue, asyncify} from 'async'

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

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

où je pourrais écrire ça

import {queue} from 'async'

async function run () {
  await someStuff()
}

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

Ajout de la documentation pour asyncify . Je vais garder cela ouvert pour le comportement d'asyncify-ing automatique.

À ce sujet, j'expérimentais l'utilisation de la même base de code et une interface Promise pour les méthodes qui utilisent le rappel comme dernier paramètre. vérifiez-le !

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'est-ce que tu en penses? Je pense que cela pourrait être facile d'adapter la bibliothèque. Voyez par exemple comment fonctionne la bibliothèque de gestion cb et promise .

Très intéressant. Si Async gérait correctement les fonctions qui renvoient des promesses, il pourrait également accepter assez facilement les fonctions Async avec promesse. Cela fonctionnerait :

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

Il serait beaucoup plus facile de combiner des fonctions Async.

Le problème aujourd'hui est que les rappels sont facultatifs. Laisser de côté le dernier argument exécute toujours la tâche. J'aimerais faire en sorte que les fonctions Async soient automatiquement curry - si vous laissez le rappel, il applique partiellement la fonction, et tout ce que vous avez à faire est de l'appeler avec un rappel. Mais vu que de nombreuses méthodes ont des paramètres facultatifs et que nous nous dirigeons vers des rappels facultatifs à tous les niveaux, vous ne pouvez pas vraiment le faire. Nos méthodes sont variadiques et vous ne pouvez pas utiliser de fonctions variadiques.

Cependant, si l'on laisse de côté le rappel final d'une méthode, elle renvoie une promesse, et si Async est configuré pour gérer les fonctions qui renvoient des promesses, c'est une combinaison intéressante. Un problème majeur est alors qu'Async devrait s'intégrer à une bibliothèque de promesses - laquelle ? Utilisons-nous global.Promise , forçant les moteurs plus anciens à se polyfiller, ou utilisons-nous quelque chose comme Bluebird ? En outre, Async est une sorte de déclaration contre les promesses - des fonctions d'ordre supérieur pour les fonctions d'acceptation de rappel, plutôt que d'adopter le paradigme Futures. Je suis tout à fait pour l'interopérabilité avec Promises, mais je pense qu'avoir des promesses de retour Async est un peu en dehors de sa philosophie de conception.

@aearly

Je pense que Promises est un flux de travail aligné sur les dernières versions du nœud (>=4). Dans cette version, les promesses sont disponibles, ma vision est donc d'utiliser le flux de travail Promise lorsque l'environnement global contient des promesses.

Il est possible d'ajouter un petit polyfill (cochez pinkie-promise ) mais à mon avis, cela n'a pas de sens de fournir un polyfill. Mieux vaut forcer l'utilisateur à mettre à niveau la version du nœud pour utiliser les dernières fonctionnalités du nœud. Vraiment, vérifiez (obtenu 6 PR)[https://github.com/sindresorhus/got/pull/140]. Les dépendances ne sont pas les bienvenues dans les très petits projets et sont utilisées partout.

Peut-être que cette fonctionnalité pourrait être intéressante à inclure après la modularisation asynchrone, que la base de code sera plus facile à adapter.

Mais définitivement, aligner asynchrone avec les promesses est totalement _must_ !

@Kikobeats :+1:

Les promesses deviennent les fonctions asynchrones de première classe. Il est donc difficile d'imaginer la bibliothèque indispensable pour l'asynchronie sans leur prise en charge complète.

Je pense que cela pourrait être implémenté sans polyfill mais avec détection de fonctionnalité: autoriser s'il existe un objet Promise global avec la méthode resolve .

@aearly bluebird ajoute la compatibilité du navigateur à la liste de ses polyfilling. Je pense qu'il pourrait être approprié de l'utiliser.

@martinheidegger Bluebird est trop gros pour ça. Il diffusera 76 Ko (minifié) pour une prise en charge simple des méthodes promises.

Encore une fois, l'utilisation de l'interface de rappel ou de promesses dans votre flux de travail backend est un processus naturel basé sur la version de votre nœud.

  • Si vous avez un backend plus long (2 ans ou plus, peut-être), vous utilisez la version 0.10 ou 0.12 , donc, votre code est écrit dans le style de rappel.
  • Si votre backend a moins de ~ 6 mois et que vous utilisez >=4 version de nœud

Mais en aucun cas vous n'avez un style mixte.

Il n'est donc pas nécessaire d'ajouter une dépendance pour le support Promises ; Si async prend en charge les promesses un jour dans le futur, vous pouvez l'utiliser si votre version de nœud prend en charge les promesses.

Cas extrême : _J'utilise une ancienne version de nœud mais mon backend est écrit en utilisant les promesses style_. Ensuite, vous avez défini un objet Promises comme global ou en avez défini un avant d'utiliser async . Tout ce que vous voulez. Simplement.

Même comportement côté frontend. Aucune dépendance n'est nécessaire.

Hmmn, il semble que les mêmes problèmes que les promesses d'il y a 4-5 ans s'appliquent toujours. Si tout le monde utilisait le nœud 4 ou une version ultérieure et des navigateurs modernes prenant en charge ES6, nous pourrions facilement utiliser les promesses en interne, le cas échéant.

Le problème est que nous laissons notre nœud 0.12 et les utilisateurs de navigateurs plus anciens dans la poussière, les obligeant à se polyfiller. Quel polyfill utilisent-ils ? Nous ne voudrions pas en regrouper un, même la promesse du petit doigt a du poids. De plus, les personnes qui utilisent des promesses en dehors de la promesse ES6 standard voudront utiliser bluebird ou q etc., quel que soit ce qu'elles utilisent. Je ne veux pas exiger l'utilisation d'un polyfill -- npm i -S async devrait être tout ce que les gens doivent faire.

Async a également été en quelque sorte une réaction contre Promises - une autre façon de gérer le code asynchrone. Commencer à utiliser Promises semble être un pas en arrière par rapport à cela. Des rappels correctement gérés peuvent être tout aussi puissants que les promesses (et dans de nombreux cas, plus rapides, car les promesses ont un report de boucle d'événement intégré).

Je suis tout à fait pour l'interopérabilité avec les promesses, si une fonction reçoit une promesse ou un autre "thnnable", nous devrions certainement en profiter. Mais je pense que nous devrions éviter de créer et/ou de retourner des promesses en interne, simplement parce que la prise en charge d'ES6 sur toutes les plateformes a encore du chemin à parcourir.

D'accord, les promesses ne sont pas bon marché à créer ou à traiter. Je préfère voir quelque chose comme ça comme une extension opt-in. Les promesses sont grandes mais vous n'en voudrez pas toujours

À mon humble avis, après avoir migré beaucoup de code de nœud vers les promesses + co + rendement, je n'ai pas trouvé de remplacement direct uniquement pour .eachLimit() . Probablement, la liste des cas utiles est bien moindre qu'il n'y paraît à première vue et peut être traitée avec un package séparé.

J'aime la petite extension de @Kikobeats , il peut être judicieux de la recommander dans le fichier readme (/cc @aearly).

Je serais fortement contre le support officiel des promesses en async pour des raisons évoquées par moi-même et d'autres utilisateurs.

@megawac Qu'en est-il du cas où une fonction renvoie une promesse ? par exemple l'exemple de @SEAPUNK .

@megawac I Ajout de la prise en charge du style de rappel, des tests et de la construction du navigateur dans promise-async . Alors si quelqu'un veut utiliser Promise, je pense que c'est prêt :+1:

@aearly , ce serait bien je suppose (donc =) mais je préfère le laisser dans le plugin
terre personnellement

Le vendredi 22 janvier 2016 à 14h17, Kiko Beats [email protected]
a écrit:

@megawac https://github.com/megawac I Ajout de la prise en charge du style de rappel
et tests pour promise-async
https://github.com/Kikobeats/promise-async#promise -async. Puis si
tout le monde veut utiliser Promise, je pense que c'est prêt [image: :+1:]

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/caolan/async/issues/956#issuecomment-174016628 .

Voici un autre package qui promet toutes les méthodes asynchrones disponibles :
https://github.com/eladnava/koa-async

Je pense que tout comme il y a async.asyncify, il pourrait y avoir une fonction async.promisify.

Ensuite, je peux juste attendre async.promisify(async.mapLimit(x,10, mapper))

Je ne m'y opposerais pas si vous voulez créer une pull request

Le samedi 17 décembre 2016 à 16h57, Manoj Patel [email protected]
a écrit:

Je pense que tout comme il y a async.asyncify, il pourrait y avoir un async.promisify
fonction.

Ensuite, je peux juste attendre async.promisify(async.mapLimit(x,10, mapper))

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/caolan/async/issues/956#issuecomment-267789633 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/ADUIEKJIDulPHAn_SeEZbiPb3t7ORGnpks5rJFqvgaJpZM4Gh1fr
.

J'utilise la méthode bluebird pour convertir les rappels en promesses afin que les méthodes async deviennent :

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

Exemple JSFiddle

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