2017-08-08 172 views
0

我使用功能_getLogFileUrls,它执行POST请求并将数据返回给回调函数。返回的数据正被添加到数组中。多个POST请求的异步问题

函数_getLogFileUrls在一个循环中被调用。

如何在所有请求完成后返回结果数组?

我明白setTimeout是这种方法的错误方式,我写代码的方式是创建一个回调地狱。我如何摆脱setTimeout函数而不涉及各种异步问题。

// 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); 
    }); 
} 

回答

2

使用async.eachOf遍历阵列,并且每个元素上应用的异步功能:

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 

}); 

////编辑

异步模块文档:https://caolan.github.io/async/docs.html

换一个代码:

 _.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); 

随着

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

不知道我得到了它,你的意思使用异步模块?然后调用_getLogFileUrls来代替myAsyncFunction? –

+0

请参阅编辑中的更改 – Dafuck