2016-03-29 83 views
0

以下函數接收一系列鏈接並掃描遠程網站,每頁獲得10篇博文,然後使用async.waterfall獲得博客文章的每條評論。嵌套的async.eachSeries堆棧迭代

// @param {Array} url 
export default function getData(url, cb) { 
    const arrayOfPosts = []; 
    // Outer loop 
    async.eachSeries(url, (link, topLVLcb) => { 

    // Waterfall 
    async.waterfall([ 

     // Collects links to posts 
     callback => { 
     request(link, (err, response, body) => { 
      console.log(`working on ${link}`); 

      const $ = cheerio.load(body); 

      // OVERALL 10 LINKS PER ONE BLOGPOST 
      $('.blogpost').each((i, element) => { 

      // build post ojbect 

      const post = { 
       content, 
       link, 
       comments: [] 
      } 
      arrayOfPosts.push(post); 
      }); 
      callback(null, arrayOfPosts); 
     }); 
     }, 

     // Looks for details in given post 
     (arrOfPosts, postDetailsCallback) => { 
     let counter = 1; 

     // Inner loop through 10 links 
     async.eachSeries(arrOfPosts, (post, eachSeriesCallback) => { 
      request(post.link, (err, response, body) => { 
      console.log(counter++); 
      const $ = cheerio.load(body); 
      $('.comment').each((i, element) => { 

       // build comment 

       const comment = { 
       author, 
       content 
       }; 

       post.comments.push(comment); 
      }); 
      eachSeriesCallback(null); 
      }); 
     }, postDetailsCallback); 
     } 
    ], err => { 
     console.log('DONE PAGE'); 
     console.log('*************************'); 
     topLVLcb(err); 
    }); 
    }, (result, err) => { 
    if (err) { 
     throw err; 
    } else { 
     console.log('DONE ALL'); 
     cb(arrayOfPosts); 
    } 
    }); 
} 

它提供的輸出是這樣的:

working on www.mywebsite.com/ 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
DONE PAGE 
************************************************************** 
working on www.mywebsite.com/posts/1 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
DONE PAGE 
************************************************************** 

而且這十個遞增每一頁,與每個迭代另起爐竈。它應該掃描每頁10次。我認爲我已經搞砸了一些回調,但我無法弄清楚已經有幾個小時了。這是我第一個nodejs異步代碼,它非常令人難以置信。

+0

那你是一個錯誤第二行.const arrayOfPosts是全局的,每次迭代它增長0,10,20,30,40,50 ....等等! – vkstack

回答

1

好像你在頂級arrayOfPosts中存儲所有帖子,但這意味着在你的第二個瀑布函數中,你將從頭開始處理所有帖子,因爲這是你傳遞給回調函數的東西。因此,在您收集指向帖子的鏈接的第一個回調函數中,您應該有一個本地數組的帖子,您可以傳遞給下一個回調函數。

+0

謝謝,這些小細節最讓你感到困惑。 –

1

arrayOfPost[]是全球每一個async.waterfall ......每個 URL元素在url你應該創建一個新的arrayOfPost[]等作爲 如下....

export default function getData(url, cb) { 
    const arrayOfPosts = []; 
    // Outer loop 
    async.eachSeries(url, (link, topLVLcb) => { 
     var tmpArr=[]; 
    // Waterfall 
    async.waterfall([ 

     // Collects links to posts 
     callback => { 
     request(link, (err, response, body) => { 
     console.log(`working on ${link}`); 

    const $ = cheerio.load(body); 

    // OVERALL 10 LINKS PER ONE BLOGPOST 
    $('.blogpost').each((i, element) => { 

     // build post ojbect 

     const post = { 
      content, 
      link, 
      comments: [] 
     } 
     tmpArr.push(post); 
     arrayOfPosts.push(post); 
}); 
    callback(null, tmpArr);//this tmpArr which is being passed will always cantain 10 items(posts) so there will be 10 iterations for each element in url 
}); 
}, 

    // Looks for details in given post 
    (arrOfPosts, postDetailsCallback) => { 
     let counter = 1; 

     // Inner loop through 10 links 
     async.eachSeries(arrOfPosts, (post, eachSeriesCallback) => { 
      request(post.link, (err, response, body) => { 
      console.log(counter++); 
      const $ = cheerio.load(body); 
      $('.comment').each((i, element) => { 

       // build comment 

       const comment = { 
        author, 
        content 
       }; 

      post.comments.push(comment); 
     }); 
      eachSeriesCallback(null); 
     }); 
    }, postDetailsCallback); 
    } 
    ], err => { 
     console.log('DONE PAGE'); 
     console.log('*************************'); 
     topLVLcb(err); 
    }); 
}, (result, err) => { 
     if (err) { 
      throw err; 
     } else { 
      console.log('DONE ALL'); 
      cb(arrayOfPosts); 
     } 
    }); 
} 
+0

謝謝你的回答,但是這段代碼不會工作,因爲在最底層的'cb'期望一個數組從這個函數中提取出來。 –

+0

更新回答檢查! – vkstack