代码之家  ›  专栏  ›  技术社区  ›  Amal

NodeJs:对请求url使用异步-Post方法在执行所有url之前发送响应

  •  1
  • Amal  · 技术社区  · 7 年前

    我有一个post方法,其请求输入是newLink对象的列表(newLink具有linkUrl和status属性) 我正在使用异步。用于在我的URL上迭代以检查链接是否处于活动状态的映射。

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

    基本上,在第一个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 回复  |  直到 7 年前
        1
  •  2
  •   Ahmed Dinar    7 年前

    这个 callback 属于 async.map proxiedRequest . 您的代码现在正在做什么:调用 回调 代理请求 return false; 在异步函数中不工作。你应该像这样返回新状态 callback(null, newLink) . 处理完所有请求后 newLinkDetails newLink .

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

    如果您需要维持订单,请用户 mapSeries

    请阅读 doc of 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);
      });
    });
    
        2
  •  1
  •   Mikey    7 年前

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

    • callback 在异步函数期间至少且最多一次。

    • 呼叫 回调 回调 通过 error 并停止进一步执行异步函数,例如。 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() 回调 需要在其第二个参数中传递布尔值。