2012-03-26 10 views
0

Was ich tun möchte, ist ein Array von Studenten zu jedem Manager (in einem Array) hinzuzufügen.coffeescript durch das Array schleifen und Werte hinzufügen

Dies ist, wo ich stecken:

 for sup in sups 
     do(sup) -> 
      sup.students_a = "This one works" 
      getStudents sup.CLKEY, (studs) -> 
      sup.students_b = "This one doesn't" 
     cback sups 

EDIT: Nach einigem Nachdenken kann geschehen, was ist, dass es die „sudents_b“ Daten an die sups Array erweitert, aber die sups Array über diese Funktion zurückgegeben werden, bevor diese Arbeit ausgeführt wird. Also, ich denke, ich sollte diese Arbeit zu einer Funktion bewegen und nur Sups zurückgeben, nachdem ein anderer Rückruf durchgeführt wurde?

Für Kontext, hier ist der Kern dieses Code:

odbc = require "odbc" 

module.exports.run = (managerId, cback) -> 
    db2 = new odbc.Database() 
    conn = "dsn=mydsn;uid=myuid;pwd=mypwd;database=mydb" 
    db2.open conn, (err) -> 
    throw err if err 

    sortBy = (key, a, b, r) -> 
     r = if r then 1 else -1 
     return -1*r if a[key] > b[key] 
     return +1*r if b[key] > a[key] 
     return 0 

    getDB2Rows = (sql, params, cb) -> 
     db2.query sql, params, (err, rows, def) -> 
     if err? then console.log err else cb rows 

    getManagers = (mid, callback) -> 
     supers = [] 
     queue = [] 

     querySupers = (id, cb) -> 
     sql = "select distinct mycolumns where users.id = ? and users.issupervisor = 1" 
     getDB2Rows sql, [id], (rows) -> 
      for row in rows 
      do(row) -> 
       if supers.indexOf row is -1 then supers.push row 
       if queue.indexOf row is -1 then queue.push row 
      cb null 

     addSupers = (id) -> # todo: add limit to protect against infinate loop 
     querySupers id, (done) -> 
      shiftrow = queue.shift() 
      if shiftrow? and shiftrow['CLKEY']? then addSupers shiftrow['CLKEY'] else 
      callback supers 

     addMain = (id) -> 
     sql = "select mycolumns where users.id = ? and users.issupervisor = 1" 
     getDB2Rows sql, [id], (rows) -> 
      supers.push row for row in rows 

     addMain mid 
     addSupers mid 

    getStudents = (sid, callb) -> 
     students = [] 

     sql = "select mycols from mytables where myconditions and users.supervisor = ?" 
     getDB2Rows sql, [sid], (datas) -> 
     students.push data for data in datas 
     callb students 

    console.log "Compiling Array of all Managers tied to ID #{managerId}..." 
    getManagers managerId, (sups) -> 
     console.log "Built array of #{sups.length} managers" 
     sups.sort (a,b) -> 
     sortBy('MLNAME', a, b) or # manager's manager 
     sortBy('LNAME', a, b) # manager 
     for sup in sups 
     do(sup) -> 
      sup.students_a = "This one works" 
      getStudents sup.CLKEY, (studs) -> 
      sup.students_b = "This one doesn't" 
     cback sups 

Antwort

1

Sie sind richtig, dass Ihr Rückruf cback subs bevor auch nur die ersten getStudents ausgeführt wird ausgeführt, hat es Callback mit dem studs Array. Da Sie dies für ein ganzes Array tun möchten, kann es mit nur einer for Schleife ein wenig haarig wachsen.

Ich empfehle async immer für diese Dinge:

getter = (sup, callback) -> 
    getStudents sup.CLKEY, callback 

async.map sups, getter, (err, results) -> 
    // results is an array of results for each sup 
    callback() // <-- this is where you do your final callback. 

Edit: Oder wenn Sie students auf jeder sup setzen wollen, müssten Sie diese getter:

getter = (sup, callback) -> 
    getStudents sup.CLKEY, (studs) -> 
    sup.students = studs 
    // async expects err as the first parameter to callbacks, as is customary in node 
    callback null, sup 

Edit: Auch sollten Sie wahrscheinlich die Knoten benutzerdefinierte Weitergabe von err als Tanne folgen st Argument für alle Rückrufe, und richtige Fehlerprüfung.

+1

Vielen Dank - das funktioniert perfekt! Außerdem "err" zu allen meinen Rückrufen hinzufügen. – jiy

+0

Großartig! Ich empfehle Ihnen, die kurze, aber ausgezeichnete Dokumentation von async zu lesen. Es gibt viele Extras für 'map',' forEach', 'filter' usw. mit Callbacks, zusammen mit Kontrollfluss wie' parallel', 'queue' und mehr. –

Verwandte Themen