web-dev-qa-db-fra.com

Node.js async à synchroniser

Comment faire pour que ça marche

var asyncToSync = syncFunc();

function syncFunc() {
    var sync = true;
    var data = null;
    query(params, function(result){
        data = result;
        sync = false;
    });
    while(sync) {}
    return data;
}

J'ai essayé d'obtenir la fonction de synchronisation à partir d'Async One, j'en ai besoin pour utiliser la requête asynchrone FreeTds comme Sync One

22
user840250

Utilisez deasync - un module écrit en C++ qui expose la boucle d'événements Node.js à JavaScript. Le module expose également une fonction sleep qui bloque le code suivant mais ne bloque pas le thread entier, ni ne provoque une attente occupée. Vous pouvez placer la fonction sleep dans votre boucle while:

var asyncToSync = syncFunc();

function syncFunc() {
    var sync = true;
    var data = null;
    query(params, function(result){
        data = result;
        sync = false;
    });
    while(sync) {require('deasync').sleep(100);}
    return data;
}
19
abbr

Vous pouvez le faire avec node-sync lib

var sync = require('sync');

sync(function(){
  var result = query.sync(query, params);
  // result can be used immediately
})

Remarque: votre requête doit utiliser un appel de rappel standard (avec erreur d'abord): rappel (erreur, résultat). Si vous ne pouvez pas changer la méthode de requête, créez simplement un wrapper .async () (voir le lien github).

9

De nos jours, ce modèle de générateur peut être une solution fantastique dans de nombreuses situations:

// nodejs script doing sequential prompts using async readline.question function

var main = (function* () {

  // just import and initialize 'readline' in nodejs
  var r = require('readline')
  var rl = r.createInterface({input: process.stdin, output: process.stdout })

  // magic here, the callback is the iterator.next
  var answerA = yield rl.question('do you want this? ', res=>main.next(res))    

  // and again, in a sync fashion
  var answerB = yield rl.question('are you sure? ', res=>main.next(res))        

  // readline boilerplate
  rl.close()

  console.log(answerA, answerB)

})()    // <-- executed: iterator created from generator
main.next()     // kick off the iterator, 
                // runs until the first 'yield', including rightmost code
                // and waits until another main.next() happens
9
drodsou

J'utilise syncrhonize.js avec beaucoup de succès. Il y a même une demande d'extraction en attente (qui fonctionne assez bien) pour prendre en charge les fonctions asynchrones qui ont plusieurs paramètres. Beaucoup mieux et plus facile à utiliser que le nho de synchronisation de noeud. Bonus supplémentaire grâce à sa documentation facile à comprendre et approfondie, contrairement à la synchronisation des nœuds.

3
shellscape

Le problème que vous rencontrez est que votre boucle étroite est bloquante. Je ne pense donc pas que votre rappel de requête sera jamais exécuté. Je pense que vous devez utiliser setTimeout ou similaire pour empêcher la fonction de bloquer, mais si vous le faites, la fonction reviendra avant l'appel du rappel. Cette fonctionnalité doit être implémentée à un niveau inférieur.

Si vous êtes dans le navigateur, vous pouvez consulter cet article . Dans le nœud, vous devez vous fier à l'implémentation de tout ce que vous interrogez. Il peut ou non fournir des méthodes synchrones.

2
Maus