2017-08-08 2 views
0

Ich verwende eine Funktion _getLogFileUrls, die eine POST Anfrage ausführt und die Daten an eine Rückruffunktion zurückgibt. Die zurückgegebenen Daten werden einem Array hinzugefügt.Asynchrone Probleme für mehrere POST-Anfrage

Die Funktion _getLogFileUrls wird in einer Schleife aufgerufen.

Wie gebe ich das resultierende Array zurück, nachdem alle Anforderungen abgeschlossen wurden?

Ich verstehe, setTimeout ist ein falscher Weg für diesen Ansatz und die Art, wie ich schreibe den Code ist eine Rückruf-Hölle. Wie werde ich die setTimeout Funktion los, ohne in alle Arten von asynchronen Problemen zu geraten.

// app.post('/api/getLogs', auth, loggingAPI.getLogs); // Make API request 

function getLogs(req, res) { 
    if (! req.body.id) { 
     return res.status(500).send('Please check the params!'); 
    } 

    var date; 

    if (req.body.date) { 
     date = req.body.date; 
    } else { 
     date = new Date().toISOString().slice(0,10); 
    } 

    var sqlQuery = "SELECT `LogFileID` FROM `logs_data` WHERE `EmpID` = '" + req.body.id + "' AND DATE(`Timestamp`) = '" + date + "'", 
     resArray= []; 

    hitThisQueryForMe(sqlQuery, res, function(rows) { 
     if (! rows.length) res.json(rows); 

     _.each(rows, function(item) { 
      console.log('item: ' + item.LogFileID); 
      _getLogFileUrls(item.LogFileID, function(response) { 
       resArray.push(response); 
      }); 
     }); 

     setTimeout(function() { 
      console.log('final urls: ' + JSON.stringify(resArray)); 
      res.send(resArray); 
      resArray = []; 
     }, 4000); 

    }); 
} 

function _getLogFileUrls(logFileId, callback) { 
    var request = require('request'), 
    config = require('../../config.js');  

    var fileParams = { 
     fileName: 'LogFiles/' + logFileId  
    }; 

    request.post({ 
     url: config.filesServiceUrl + 'get-logfile-urls', 
     json: fileParams 
    }, function(error, response, body) { 
     if (!error && response.statusCode === 200) { 
      callback(body); 
     } else { 
      console.log('err requesting logs: ' + JSON.stringify(error)); 
      res.status(400).send('Err requesting logs:'); 
     } 
    }).on('error', function(err) { 
     console.log('File service error for Logs: ' + err); 
    }); 
} 

Antwort

2

Verwenden async.eachOf über dem Array iterieren und eine Async Funktion für jedes Element gilt:

async.eachOf(myArray, function(myElementInArray, it, callback){ 

    // call async function on element 
    myAsyncFunction(myElementInArray, function(err){ 
     if(err) 
     return callback(err); // abort async flow 
     else 
     return callback(); 
    }); 

}, function(err){ 
    // final callback called when the flow is finished 

}); 

//// EDIT

async Modul Dokumentation: https://caolan.github.io/async/docs.html

Diesen Code ersetzen:

 _.each(rows, function(item){    
      console.log('item: ' + item.LogFileID); 
      _getLogFileUrls(item.LogFileID, function(response){ 
       resArray.push(response);    
      });   
     }); 

     setTimeout(function(){ 
      console.log('final urls: ' + JSON.stringify(resArray)); 
      res.send(resArray); 
      resArray = []; 
     }, 4000); 

Mit

var async = require("async"); 
var resArray = []; 
async.eachOf(rows, function(item, it, callback){ 

    console.log('item: ' + item.LogFileID); 
    // call async function on element 
    _getLogFileUrls(item.LogFileID, function(response){ 
     resArray.push(response); 
     return callback(); 
    }); 

}, function(err){ 
    // final callback called when the flow is finished 
    console.log('final urls: ' + JSON.stringify(resArray)); 
    res.send(resArray); 
}); 
+0

nicht sicher, ich habe es, tun Sie das Asynchron-Modul bedeuten mit? und dann Aufruf der _getLogFileUrls anstelle von myAsyncFunction? –

+0

Siehe Änderung in Bearbeitung – Dafuck

Verwandte Themen