2013-05-16 9 views
18

Wie synchronisieren kann ich diese ArbeitNode.js async

var asyncToSync = syncFunc(); 

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

Ich habe versucht, von Sync-Funktion zu erhalten async ein, ich es brauche freetds Asynchron-Abfrage als sync ein

+4

Async Rückrufe immer laufen, nachdem die Funktion Stapel gelöscht hat. Daher ist es nicht möglich, ein Ansagergebnis synchron zurückzugeben. Jede synchrone Funktion, die eine asynchrone Aktion ausgelöst hat, muss vor dem Start der asynchronen Aktion zurückgegeben worden sein. ** Stattdessen ** möchten Sie Ihre äußere Funktion * auch * asynchron machen, indem Sie einen Callback annehmen, der im Callback zu 'query' aufgerufen wird. – apsillers

+1

Führt die Abfragefunktion einen Datenbankaufruf durch? Wenn dies der Fall ist, kann der DB-Client eine synchrone Version dieser Abfragefunktion bereitstellen. – helpermethod

+0

Duplizieren: [Wie blockiere ich asynchrone Funktionen in JavaScript] (http://stackoverflow.com/questions/4345945/how-to-block-on-asynchronous-functions-in-javascript) (aber nicht viele gute erklärende Antworten) – apsillers

Antwort

12

Verwenden Sie deasync - ein Modul in C++ geschrieben, die Node.js-Ereignisschleife zu JavaScript offen legt. Das Modul stellt auch eine sleep-Funktion zur Verfügung, die den nachfolgenden Code blockiert, aber nicht den gesamten Thread blockiert, noch eine Busy-Wartezeit annimmt. Sie können die sleep Funktion in Ihrem while Schleife setzen:

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; 
} 
+1

Dies ist die einzige, die Sie nicht innerhalb einer Fiber ausführen müssen (was Sie nicht immer tun können, wenn Sie den Anrufcode nicht kontrollieren) – tmandry

+0

FANTASTISCH !!! Ich mag Deasync – Aminadav

+0

In der Tat! Dies ist der einzige, der mit meinem Fall gearbeitet hat. Vielen Dank! – yoshi

9

Sie können zu verwenden, tun sie es mit node-sync lib

var sync = require('sync'); 

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

Hinweis: Ihre Anfrage standart Rückruf Anruf (mit Fehler zuerst) verwenden müssen: Rückruf (Fehler, Ergebnis). Wenn Sie die Abfragemethode nicht ändern können, erstellen Sie einfach den .async() -Wrapper (siehe GitHub-Link).

+1

Ich habe Async-Funktion mit Callback err und resutls, ist "sync (function() {})" in der Lage, Wert in normalen js Sync-Funktion zurückzugeben? – user840250

+0

Nein Sync() ist nur neue Thread-Kontext. Es gibt nichts zurück. Umwickeln Sie einfach den gesamten Code und verwenden Sie .sync für asynchrone Funktionen. –

3

Ich habe syncrhonize.js mit großem Erfolg verwendet. Es gibt sogar eine ausstehende Pull-Anforderung (die ganz gut funktioniert), um asynchrone Funktionen mit mehreren Parametern zu unterstützen. Weit besser und einfacher zu bedienen als Node-Sync-imho. Zusätzlicher Bonus, dass es leicht verständliche und gründliche Dokumentation gibt, während Node-Sync dies nicht tut.

1

Das Problem, das Sie haben, ist, dass Ihre enge while-Schleife blockiert. Ich denke also nicht, dass Ihr Abfrage-Callback jemals ausgeführt wird. Ich denke, Sie müssen setTimeout oder ähnliches verwenden, um zu verhindern, dass die Funktion blockiert, aber wenn Sie dies tun, wird die Funktion zurückkehren, bevor der Rückruf aufgerufen wird. Diese Funktionalität muss auf einer niedrigeren Ebene implementiert werden.

Wenn Sie im Browser sind, können Sie this article auschecken. Im Knoten müssen Sie sich auf die Implementierung dessen verlassen, was Sie abfragen. Es kann synchrone Methoden bereitstellen oder nicht.

7

Heute kann dieser Generator Muster eine fantastische Lösung in vielen Situationen:

// 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 
Verwandte Themen