NodeJs:使用async for request url - Post方法在执行所有url之前发送响应

时间:2017-09-14 06:30:57

标签: node.js async.js

我有一个post方法,其请求输入是newLink对象列表(带有属性linkUrl和status的newLink) 我正在使用async.map迭代我的URL以检查链接是否有效。

newLinks包含{www.google.com,www.nourl.com,www.xyz.com}等链接。我希望在处理完所有请求并将相应状态设置为true或false之后,我希望此项发送使用res.send(newLinks)

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

所以基本上在这里,在第一个url请求之后,我的代码是在异步循环之外执行函数。我认为async只允许下一段代码在所有url被验证后才能执行。

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

2 个答案:

答案 0 :(得分:2)

callback的{​​{1}}应在async.map内调用。您的代码现在正在做什么:在proxiedRequest完成之前立即调用callback。另外proxiedRequest在异步函数中不起作用。您应该返回此状态return false;的新状态。处理完所有请求后,callback(null, newLink)将成为所有newLinkDetails的数组。

  

请注意,由于此函数将iteratee并行应用于每个项目,因此无法保证iteratee函数将按顺序完成。

如果您需要保留订单,请先将用户mapSeries投放。

请阅读doc of async.map了解更多信息。希望它有所帮助。

newLink

答案 1 :(得分:1)

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

  • 在异步功能中,始终至少调用一次callback和。

  • 仅在异步功能完成或发生错误时调用callback。如果后者发生,请调用通过callback的{​​{1}}并停止进一步执行异步功能,例如error

我会修改你的代码如下:

return callback(error)

如果您只想取回有效链接,可能还需要查看async.filterSeries()。这里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); }); }); 需要在其第二个参数中传递一个布尔值。