NodeJs:使用请求url的asynchronous – Post方法发送响应之前执行的所有url

我有一个post方法,其请求input是一个newLink对象列表(具有属性linkUrl和状态的newLink)我使用async.map迭代我的URL检查链接是否是活动的。

newLinks包含像{www.google.com,www.nourl.com,www.xyz.com}这样的链接,我希望毕竟这个请求被处理,并设置相应的状态为true或false,我希望这个使用res来发送。发送(newLinks)

但控制台给出了以下结果:“www.google.com已经启动”,然后调用res.send(),然后执行“www.nourl.com is up”和“www.xyz.com is up”

所以基本上,在第一个url请求之后,我的代码在asynchronous循环之外执行函数。 我认为asynchronous将只允许所有的urlvalidation后才能执行下一段代码。

app.post('/myposturl', function(req , res){ var request = require('request'); let linkDetails= req.body.linkDetails; var i = 0; async.map(linkDetails, function(newLink, callback) { var Url = "url"; var url = newLink.linkUrl; var proxiedRequest = request.defaults({'proxy': Url}); proxiedRequest(url , function (error, response, body) { if(error){ console.log('Err: '+ error); } if (!error) { if(response.statusCode == 200 || response.statusCode == 201 || response.statusCode == 202){ console.log(url + ' is up!!'); newLink.isActive = true; } if(response.statusCode == 301 || response.statusCode == 302){ console.log(url + ' is redirecting us!!'); return false; } } }); callback(); } , function(err, linkDetails) { res.send(linkDetails); }); //tried res.send here as well. }); } 

async.mapcallback应该在proxiedRequest调用。 你的代码现在正在做什么:在proxiedRequest完成之前立即调用callback 。 也return false; 在asynchronousfunction中不起作用。 你应该返回新的状态,像这个callback(null, newLink) 。 处理newLinkDetails所有请求后, newLinkDetails将成为所有newLink的数组。

请注意,由于此函数并行地将迭代应用于每个项目,因此不能保证迭代函数将按顺序完成。

如果您需要保留订单,用户mapSeries insted 。

请阅读更多的async.map的文档 。 希望能帮助到你。

 app.post('/myposturl', function(req , res){ //other codes async.map(linkDetails, function(newLink, callback) { //other codes proxiedRequest(url , function (error, response, body) { if(error){ console.log('Err: '+ error); callback(error); //^ ^ ^ ^ ^ // Validation failed, return from here } else { //some validation & set newLink.isActive callback(null, newLink); // ^ ^ ^ ^ ^ //return newLink status by invoking the callback } }); }, function(err, newLinkDetails) { //err = if any Validation failed // now all the request are processed,newLinkDetails is array of all newLink's res.send(newLinkDetails); }); }); 

通常在使用async.js ,我遵循以下两个原则:

  • 在asynchronousfunction期间,至less一次至多调用一次callback

  • 只有在asynchronousfunction完成或发生错误时才调用callback 。 如果后者发生,则callback通过errorcallback并停止asynchronous函数的进一步执行,例如return callback(error)

我会修改你的代码如下:

 var request = require('request'); app.post('/myposturl', function (req , res) { async.mapSeries(req.body.linkDetails || [], function(newLink, callback) { var Url = "url"; var proxiedRequest = request.defaults({ 'proxy': Url }); proxiedRequest(newLink.linkUrl, function (err, response, body) { if (err) return callback(err); // I'm assuming you don't want to stop checking the links for bad status codes if ([301, 302].indexOf(response.statusCode) > -1){ return callback(null, url + ' is redirecting us!!'); if ([200, 201, 202].indexOf(response.statusCode) == -1) { return callback(null, url + ' came back with ' + response.statusCode); console.log(url + ' is up!!'); newLink.isActive = true; callback(null, newLink); }); }, function (err, linkDetails) { // when all links get checked, it will come down here // or if an error occurs during the iteration, it will come down here console.log(err, linkdetails); res.send(linkDetails); }); }); 

如果你只想返回活动链接,你可能也想看看async.filterSeries() 。 这里的callback将需要在第二个参数中传递一个布尔值。