2017-04-20 4 views
1

Hallo, ich habe die folgende rekursive Python-Funktion, die Werte von allen Kind-Knoten summieren und ich möchte in NodeJS portieren, aber ich habe ein Problem mit Async-Aufrufen.NodeJS - Summe Async führt zu rekursiver Funktion

def getTree(parent_id, level=1): 
    c.execute('select * from users where parent_id=?', (parent_id,)) 
    rows = c.fetchall() 
    total = 0 
    for child in children: 
     total += getAsyncValue(child.id) 
     total += getTree(child.id, level+1) 
    return total 

Ich habe versucht, dies zu tun, aber ich brauche wahrscheinlich Kette es mit dem Versprechen, weil die Gesamtzahl, während ich Schleife nicht verfügbar ist, wie ich es von einer Asynchron-Funktion

getTree = function(parent_id, level=1) { 
    c.all("select * from users where parent_id="+parent_id, function(err, children) { 
    var total = 0; 
    children.forEach(function(child) { 
     total += getAsyncValue(child.id) 
     total += getTree(child.id, level+1) 
    }); 
    return total; 
    }); 
} 
+0

eine Möglichkeit, dieser Code-Port, um noch einfacher ES2016 + wäre 'async/await' (die mit süßen Güte nur Versprechen ist) - mit nur Versprechungen (und damit eine bessere Browser-Kompatibilität) –

Antwort

1

ohne sehen getAsyncValue mich kann keine vollständige Antwort geben - aber

var getAsyncValue = function(id) { 
    return new Promise((resolve, reject) => { 
     // resolve some value some how 
    }); 
}; 
// helper to make the getTree function "nicer" 
c.allAsync = function(str) { 
    return new Promise((resolve, reject) => 
     this.all(str, (err, children) => { 
      if (err) { 
       return reject(err); 
      } 
      resolve(children); 
     }) 
    ); 
}; 
var getTree = function(parent_id, level=1) { 
    return c.allAsync("select * from users where parent_id="+parent_id).then(children => 
     Promise.all(children.map(child => 
      Promise.all([getAsyncValue(child.id), getTree(child.id, level+1)]) 
      .then(([a, b]) => a + b) 
     )).then(results => results.reduce((a, b) => a + b)) 
    ); 
}; 

I denken mit Asynchron/await, kann der Code geschrieben werden als:

var getAsyncValue = async function(id) { 
    return new Promise((resolve, reject) => { 
     // resolve some value some how 
    }); 
}; 
// helper to make the getTree function "nicer" 
c.allAsync = async function(str) { 
    return new Promise((resolve, reject) => 
     this.all(str, (err, children) => { 
      if (err) { 
       return reject(err); 
      } 
      resolve(children); 
     }) 
    ); 
}; 
var getTree = async function(parent_id, level=1) { 
    let children = await c.allAsync("select * from users where parent_id="+parent_id); 
    let total = 0; 
    for (let i = 0; i < children.length; i++) { 
     let child = children[i]; 
     total += await getAsyncValue(child.id); 
     total += await getTree(child.id, level + 1); 
    } 
    return total; 
}; 
+0

ein wenig mehr beteiligt ist ja, Danke! Mein Problem war verschachtelte Promise.Alle ich denke, ist wirklich ausführlich, ohne zu warten – frx08

Verwandte Themen