2017-03-13 11 views
0

두 번째 콜백 (cbNumPages)을 호출 한 후 첫 번째 매개 변수 인 "pages"가 다음 함수의 실제 콜백 인 async waterfall을 사용하는 데 문제가 있습니다. 마지막 매개 변수 대신 "cbGetFiles"가 있어야합니다. (비동기식 폭포가 마지막 매개 변수는 항상 콜백이되어야한다고 말하면이 경우 분명히 그렇지 않습니다).NodeJs async waterfall (콜백 메서드가 함수가 아닙니다)

코드는 다음

async.waterfall 
      ([ 
       function(cbNumPages) 
       { 
        request({ 
         url: 'any-url', 
         qs: {}, 
         method: 'GET', 
         headers: { 
          'Authorization' : 'any-auth' 
         } 
        }, (err, response, body) => { 
         if (!err && response.statusCode == 200) 
         { 
          var $ = cheerio.load(body); 
          var pagesList = $('ol.aui-nav').children(); 
          if(pagesList.length<1) 
          { 
           var numPages = 1; 
          } else { 
           var numPages = pagesList.length-2; 
          } 
          console.log(numPages); 
          var pages = new Array(numPages), 
           total = numPages*20, 
           iterator = 0; 

          async.eachSeries(pages, function(page, cb) 
          { 
           if(page>1) 
           { 
            pages[iterator] = iterator; 
           }else { 
            pages[iterator] = iterator*20; 
           } 
           iterator++; 
           cb(); 
          }, function(err){ 
           if(err) cbNumPages(err); 
           cbNumPages(null, pages); 
          }); 
         } else { 
          cbNumPages(err); 
         } 
        }) 
       }, 

       function(pages, cbGetFiles) 
       { 
        var files = []; 
        var limitDate = moment().tz('Europe/Madrid').subtract(330,'days').format(); 

        async.eachSeries(pages, function(page, cb) 
        { 
         request({ 
          url: 'any-url'+page, 
          qs: {}, 
          method: 'GET', 
          headers: { 
           'Authorization' : 'any-auth' 
          } 
         }, (err, response, body) => { 
          if(!err && response.statusCode == 200) 
          { 
           var $ = cheerio.load(body); 
           var rows = $('tr[id^=\'attachment-\']'); 
           async.eachLimit(rows, 1, function(row, cb) 
           { 
            var id = row.attribs['id']; 
            var file = row.attribs['data-attachment-filename']; 
            var author = $(row).children('.creator').text().trim(); 
            var created = $(row).children('.created-date').text().trim(); 
             created = moment.tz(created, 'MMM D, YYYY', 'Europe/Madrid').format(); 
            var urlFile = 'simple-file' + $(row).children('.filename-column').children('.filename').attr('href'); 
            var extension = row.attribs['data-attachment-filename'].split('.'); 
             extension = extension[extension.length-1]; 
            if(created<limitDate && validExtensions.indexOf(extension)>-1) 
            { 
             var f = '{ "id": "' + id + '",'; 
              f += ' "file": "' + file + '",'; 
              f += ' "url": "' + urlFile + '",'; 
              f += ' "author": "' + author + '",'; 
              f += ' "modified": "' + created + '" }'; 
             files.push(JSON.parse(f)); 
            } 
            cb(); 
           }, (err) => { 
            if(err) cbGetFiles(err); 
           }); 
           cb(); 
          } else { 
           cb(err); 
          } 
         }); 
        }, function(err){ 
         if(err){ 
          cbGetFiles(err); 
         } else { 
          cbGetFiles(null, files); 
         } 
        }); 
       }, 

       function(files, cbGetAutors) 
       { 
        var filesFinal = {}; 
        for(var f in files) 
        { 
         if(!filesFinal[files[f].author]) 
         { 
          var ff = {}; 
          for(var i in files) 
          { 
           if(files[i].author === files[f].author) 
           { 
            ff[files[i].file] = files[i].url; 
           } 
          } 
          filesFinal[files[f].author] = ff; 
         } 
        } 
        cbGetAutors(null, JSON.parse(JSON.stringify(filesFinal))); 
       }, 

       function(filesFinal, cbSendEmail) 
       { 
        var authors = Object.keys(filesFinal); 
        async.eachSeries(authors, function(author, cb) 
        { 
         var name = author.split(' '); 

         var email = '[email protected]'; 
         var msg = '<p>Hi ' + author + ',</p><p>how is it going:</p><p>'; 
         for(var a in Object.keys(filesFinal[author])) 
         { 
          msg += '<p style="margin-left:20px"> '+ICON_DOC+' <a href="'; 
          msg += filesFinal[author][Object.keys(filesFinal[author])[a]]+'">'+Object.keys(filesFinal[author])[a]+'</a></p>'; 
         } 
         msg += '</p></p><p><b>NOTE: This is a no-reply address.</b></p><p>Have a nice day! '+ICON_MONKEY+'</p>'; 

         var message = { 
          text: msg, 
          from: '[email protected]', 
          to:  email, 
          bcc:  '', 
          subject: 'Sample subject', 
          attachment: [{data: msg, alternative: true}] 
         }; 

         serverEmail.send(message, function(err, message) 
         { 
          if(err) 
          { 
           cb(err); 
          } else { 
           console.log(message); 
           cb(); 
          } 
         }); 

        }, function(err){ 
         if(err) cbSendEmail(err); 
         cbSendEmail(); 
        }); 
       } 

      ], (err) => { 
       if(err) console.log(err); 
      }); 

내가 무엇을 원하는 또 다른 옵션이 있습니다 적어도 경우이 문제를 제어하거나 할 수있는 방법이 있는지 알고 싶습니다.

감사합니다.

+1

,'사용'return' . http://caolan.github.io/async/의 "Common Pitfalls"섹션을 확인하십시오. – Sangharsh

+1

@Sangharsh가 문제가된다면 그 콜백이 이미 호출되었습니다. 오류가 발생하지 않습니까? @avilac'any-url'의 리턴 코드가 200이 아니므로'cbNumPages (err)'과'err'이'null' 인 호출이 가능합니까? 이것은'async'가 어떤 에러도 리턴 값도 제공하지 않는다고 생각하게 할 것이고 콜백은'waterfall'의 두 번째 함수에 첫 번째 인수로 전달됩니다. – YSK

+0

@YSK 귀하의 추측은 맞을 가능성이 큽니다. 내 의견은 코딩 연습에 관한 것입니다. – Sangharsh

답변

2

비동기 폭포를 사용하는 것이 좋습니다 (깔끔한) 방법입니다.

콜백 기능을 사용하기 전에 return을 사용해야합니다. 코드에 추가했습니다.

또한 각 시리즈를 중첩하는 경우 상위 콜백 함수와는 다른 이름을 콜백 함수에 부여하는 것이 좋습니다.

내가 'inner_cb'

업데이트 코드에 자식 async.series의 'CB를'변경 : 코드`경우 (ERR) cbNumPages (ERR)에서

async.waterfall 
([ 
    funcOne, 
    funcTwo, 
    funcThree, 
    funcFour  
], (err) => { 
    if(err) console.log(err); 
}); 

funciton funcOne(cbNumPages) { 
    request({ 
     url: 'any-url', 
     qs: {}, 
     method: 'GET', 
     headers: { 
      'Authorization' : 'any-auth' 
     } 
    }, (err, response, body) => { 
     if (!err && response.statusCode == 200) 
     { 
      var $ = cheerio.load(body); 
      var pagesList = $('ol.aui-nav').children(); 
      if(pagesList.length<1) 
      { 
       var numPages = 1; 
      } else { 
       var numPages = pagesList.length-2; 
      } 
      console.log(numPages); 
      var pages = new Array(numPages), 
       total = numPages*20, 
       iterator = 0; 

      async.eachSeries(pages, function(page, cb) 
      { 
       if(page>1) 
       { 
        pages[iterator] = iterator; 
       }else { 
        pages[iterator] = iterator*20; 
       } 
       iterator++; 
       return cb(); 
      }, function(err){ 
       if(err) return cbNumPages(err); 
       return cbNumPages(null, pages); 
      }); 
     } else { 
      return cbNumPages(err); 
     } 
    }) 
} 

function funcTwo(pages, cbGetFiles) { 
    var files = []; 
    var limitDate = moment().tz('Europe/Madrid').subtract(330,'days').format(); 

    async.eachSeries(pages, function(page, cb) 
    { 
     request({ 
      url: 'any-url'+page, 
      qs: {}, 
      method: 'GET', 
      headers: { 
       'Authorization' : 'any-auth' 
      } 
     }, (err, response, body) => { 
      if(!err && response.statusCode == 200) 
      { 
       var $ = cheerio.load(body); 
       var rows = $('tr[id^=\'attachment-\']'); 
       async.eachLimit(rows, 1, function(row, inner_cb) 
       { 
        var id = row.attribs['id']; 
        var file = row.attribs['data-attachment-filename']; 
        var author = $(row).children('.creator').text().trim(); 
        var created = $(row).children('.created-date').text().trim(); 
         created = moment.tz(created, 'MMM D, YYYY', 'Europe/Madrid').format(); 
        var urlFile = 'simple-file' + $(row).children('.filename-column').children('.filename').attr('href'); 
        var extension = row.attribs['data-attachment-filename'].split('.'); 
         extension = extension[extension.length-1]; 
        if(created<limitDate && validExtensions.indexOf(extension)>-1) 
        { 
         var f = '{ "id": "' + id + '",'; 
          f += ' "file": "' + file + '",'; 
          f += ' "url": "' + urlFile + '",'; 
          f += ' "author": "' + author + '",'; 
          f += ' "modified": "' + created + '" }'; 
         files.push(JSON.parse(f)); 
        } 
        return inner_cb(); 
       }, (err) => { 
        if(err) return cbGetFiles(err); 
       }); 
       return cb(); 
      } else { 
       return cb(err); 
      } 
     }); 
    }, function(err){ 
     if(err){ 
      return cbGetFiles(err); 
     } else { 
      return cbGetFiles(null, files); 
     } 
    }); 
} 

function funcThree(files, cbGetAutors) { 
    var filesFinal = {}; 
    for(var f in files) 
    { 
     if(!filesFinal[files[f].author]) 
     { 
      var ff = {}; 
      for(var i in files) 
      { 
       if(files[i].author === files[f].author) 
       { 
        ff[files[i].file] = files[i].url; 
       } 
      } 
      filesFinal[files[f].author] = ff; 
     } 
    } 
    return cbGetAutors(null, JSON.parse(JSON.stringify(filesFinal))); 
} 

function funcFour(filesFinal, cbSendEmail) { 
    var authors = Object.keys(filesFinal); 
    async.eachSeries(authors, function(author, cb) 
    { 
     var name = author.split(' '); 

     var email = '[email protected]'; 
     var msg = '<p>Hi ' + author + ',</p><p>how is it going:</p><p>'; 
     for(var a in Object.keys(filesFinal[author])) 
     { 
      msg += '<p style="margin-left:20px"> '+ICON_DOC+' <a href="'; 
      msg += filesFinal[author][Object.keys(filesFinal[author])[a]]+'">'+Object.keys(filesFinal[author])[a]+'</a></p>'; 
     } 
     msg += '</p></p><p><b>NOTE: This is a no-reply address.</b></p><p>Have a nice day! '+ICON_MONKEY+'</p>'; 

     var message = { 
      text: msg, 
      from: '[email protected]', 
      to:  email, 
      bcc:  '', 
      subject: 'Sample subject', 
      attachment: [{data: msg, alternative: true}] 
     }; 

     serverEmail.send(message, function(err, message) 
     { 
      if(err) 
      { 
       return cb(err); 
      } else { 
       console.log(message); 
       return cb(); 
      } 
     }); 

    }, function(err){ 
     if(err) return cbSendEmail(err); 
     return cbSendEmail(); 
    }); 
} 
+1

시간 내 주셔서 감사합니다. 언제나 좋은 조언이 도움이됩니다! :) – avilac

+0

항상 도와 드리겠습니다 :) –

0

@YSK가 의견에서 말했듯이, 나는 response.statusCode에서 401을 얻고 있었고 따라서 null로 잘못 표시된 cbSendEmail (err)에 놓치게되었습니다. 폭포의 첫 번째 매개 변수에서 두 번째 메소드 대신 콜백을 사용하여 다음 메소드를 작성합니다.