112 votes

La façon la plus simple d'attendre que certaines tâches asynchrones soient terminées, dans Javascript ?

Je veux laisser tomber quelques collections mongodb, mais c'est une tâche asynchrone. Le code sera :

var mongoose = require('mongoose');

mongoose.connect('mongo://localhost/xxx');

var conn = mongoose.connection;

['aaa','bbb','ccc'].forEach(function(name){
    conn.collection(name).drop(function(err) {
        console.log('dropped');
    });
});
console.log('all dropped');

La console affiche :

all dropped
dropped
dropped
dropped

Quelle est la façon la plus simple de s'assurer que all dropped seront imprimés après que toutes les collections ont été supprimées ? N'importe quel tiers peut être utilisé pour simplifier le code.

91voto

freakish Points 20067

Je vois que vous utilisez mongoose donc vous parlez de JavaScript côté serveur. Dans ce cas, je conseille de regarder le module asynchrone et d'utiliser async.parallel(...). Vous trouverez ce module vraiment utile - il a été développé pour résoudre le problème avec lequel vous êtes aux prises. Votre code peut ressembler

var async = require('async');

var calls = [];

['aaa','bbb','ccc'].forEach(function(name){
    calls.push(function(callback) {
        conn.collection(name).drop(function(err) {
            if (err)
                return callback(err);
            console.log('dropped');
            callback(null, name);
        });
    }
)});

async.parallel(calls, function(err, result) {
    /* this code will run after all calls finished the job or
       when any of the calls passes an error */
    if (err)
        return console.log(err);
    console.log(result);
});

8voto

Erwin Wessels Points 546

En développant la réponse @freakish, async propose également une méthode qui semble particulièrement adaptée à votre cas :

var async = require('async');

async.each(['aaa','bbb','ccc'], function(name, callback) {
    conn.collection(name).drop( callback );
}, function(err) {
    if( err ) { return console.log(err); }
    console.log('all dropped');
});

L'OMI, ce qui rend le code à la fois plus efficace et plus lisible. J'ai pris la liberté de supprimer le console.log('dropped') - si vous le souhaitez, utilisez ceci à la place :

var async = require('async');

async.each(['aaa','bbb','ccc'], function(name, callback) {
    // if you really want the console.log( 'dropped' ),
    // replace the 'callback' here with an anonymous function
    conn.collection(name).drop( function(err) {
        if( err ) { return callback(err); }
        console.log('dropped');
        callback()
    });
}, function(err) {
    if( err ) { return console.log(err); }
    console.log('all dropped');
});

5voto

user435943 Points 320

Je le fais sans librairies externes :

var yourArray = ['aaa','bbb','ccc'];
var counter = [];

yourArray.forEach(function(name){
    conn.collection(name).drop(function(err) {
        counter.push(true);
        console.log('dropped');
        if(counter.length === yourArray.length){
            console.log('all dropped');
        }
    });                
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X