2017-09-14 5 views
1

요청 메서드가 newLink 개체 (linkUrl 및 status 특성을 가진 newLink)의 요청 인 게시 메서드가 있습니다 async.map 링크가 활성화되었는지 여부를 확인하기 위해 내 URL을 반복 실행합니다.NodeJs : 요청 URL에 대해 비동기 사용 - 모든 URL을 실행하기 전에 응답을 보내는 게시 메서드

newLinks에는 {www.google.com, www.nourl.com, www.xyz.com}과 같은 링크가 포함되어 있습니다. 모든 요청을 처리하고 해당 상태를 true 또는 false로 설정하면 res.send (newLinks)를 사용하여 보내십시오.

그러나 콘솔은 "www.google.com is up"이고 res.send()를 호출 한 다음 "www.nourl.com is up" 및 "www.xyz.com 최대"

그래서 기본적으로 여기에 첫 번째 URL 요청 후 아래 코드는 비동기 루프 외부에서 함수를 실행하고 있습니다. async는 모든 URL의 유효성을 검사 한 후에 만 ​​다음 코드를 실행할 수 있다고 생각했습니다. callbackasync.map의는 proxiedRequest 내부

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

async.mapSeries를 사용해보세요. –

+0

시도했지만 행운을 : ( – Amal

+0

async.map 대신 async.series 시도하고 async.series 내부 forin 루프를 사용하십시오. 내 응용 프로그램 중 하나에서 시도하고 괜찮 았어. –

답변

2

를 호출해야합니다. 지금 코드가 수행중인 작업 : proxiedRequest 완료 직전에 callback을 호출하십시오. 또한 return false;은 비동기 기능에서 작동하지 않습니다. callback(null, newLink)과 같은 새 상태를 반환해야합니다. 모든 요청이 처리 된 후 newLinkDetails은 모두 newLink의 배열입니다.

이 함수는 iteratee를 각 항목에 병렬로 적용하기 때문에 iteratee 함수가 순서대로 완료된다는 보장이 없습니다.

주문을 계속해야하는 경우 사용자 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); 
    }); 
}); 
1

보통 async.js를 사용하는 경우, 나는이 두 가지 원칙을 따르

  • 는 항상 비동기 기능 중 최대 한 번에 적어도 callback를 호출합니다.

  • 비동기 기능이 완료되거나 오류가 발생한 경우에만 callback으로 전화하십시오. 후자가 발생하면 error을 전달하고 callback을 호출하고 비동기 함수의 추가 실행을 중지합니다.

    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()을 체크 아웃 할 수 있습니다 : return callback(error)

나는 다음과 같이 코드가 수정됩니다. 여기서 callback은 두 번째 인수에 부울을 전달해야합니다.