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.map
的callback
应该在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
通过error
的callback
并停止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
将需要在第二个参数中传递一个布尔值。