2017-07-21 17 views
0

URLの配列をループし、一連のURLから応答を取得してレスポンスURLを処理しようとしています。コードでは、内側のリクエストをすべて完了した後に外側のループを入力し、その結果を以下のようにしたいと思います。でURLをチェックノード。 js複数のHTTPリクエストを含むネストされた非同期マップ

https://stackoverflow.com 状態200は を行って.... ....でURLをチェック :https://example.com ..... ..... .....

合計リンク#20

しかし、私のコードでは、要求が完了する前に外側ループが終了しています。

const getHrefs = require('get-hrefs'); 
const async = require("async"); 
var req = require('request-promise'); 
var errors = require('request-promise/errors'); 

var pageUrls = ['https://stackoverflow.com','https://www.exsample.com']; 
testUrls=''; 

async.map(pageUrls, function(pageUrl,callback){ 
    //process itemA 
    req(pageUrl, function (err, response, body) { 
     console.log(pageUrl, " STATUS: ", response.statusCode); 
     if (err){ 
      return callback(err); 
     } 
     else { 
     testUrls= getHrefs(response.body); 

     async.map(testUrls, function(testUrl,callback1){ 
      linkCount++; 
       req(testUrl).catch(errors.StatusCodeError, function (reason) { 
         brokenLinks++; 
         console.log("URL: "+ testUrl+ "reason: "+ reason.statusCode); 
        }) 
        .catch(errors.RequestError, function (reason) { 

        }).finally(function() { 


        }); 

       return callback1(); 
      },function(err){ 

       callback(); 

       }) ; 
     } 
    }) 

} ,function(err){ 
    console.log("OuterLoopFinished"); 
    console.log('*************************************************************' + '\n'); 
    console.log('Check complete! || Total Links: ' + linkCount + ' || Broken Links: ' + brokenLinks); 
    console.log('*************************************************************'); 

}); 
+0

あなたは 'callback1'をあまりに早く呼び出しています。 'finally'ブロックの中に入れてみてください。 – IronGeek

+0

最後のコールバック関数(outerloopfinished)で終わっていないあなたの返事に感謝します。 – sanavstars

+0

'callback1'の呼び出しは内部の' async.map'実行の終わりをマークします(各 'testUrls'アイテム用)。 'async.map(testUrls ...'の完了は 'async.map'の各外側の' async.map'実行の終了を示す 'callback'を呼び出します)' async.map(pageUrl .. 'outerloopfinished'関数を呼び出しています... – IronGeek

答えて

0

私はあなたのアプローチを見直すべきだと思います。これにより、400のURLが作成されます。すべての要求を並行して(サブリンクのために)起動し、ホストURLから壊れたURIの数を追跡できます。これにより、スクリプトがより速く完了します。

const pageUrls = ['https://stackoverflow.com','https://www.google.com']; 
const rp = require('request-promise'); 
const allRequestPromises = []; 
const getHrefs = require('get-hrefs'); 

const checkBrokenCount = (url, host) => { 
    rp(url).then((response) => { 
    console.log('valid url', url, host); 
    // other code 
    }) 
    .catch((error) => { 
    console.log('invalid url', url, host); 
    }); 
} 

pageUrls.forEach((pageUrl)=> { 
    // Lets call all the base URLs in parallel asuming there are not incorrect. 
    allRequestPromises.push(rp({uri: pageUrl, resolveWithFullResponse: true})); 
}); 
Promise.all(allRequestPromises).then((responses) => { 
    responses.forEach((response, index) => { 
    // Promise.all guarantees the order of result. 
    console.log(pageUrls[index], response.statusCode); 
    const testUrls= getHrefs(response.body); 
    testUrls.forEach((testUrl) => { 
     checkBrokenCount(testUrl, pageUrls[index]); 
    }); 
    }); 
}); 
+0

あなたの応答がうまくいってくれてありがとうございます。しかし、すべての約束で無効なベースURLをスキップする方法は? – sanavstars

+0

Nvm simple :rpオプションでtrueが正常に動作しています – sanavstars

+0

'Promise.all'はフェイルファーストです(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all#Promise.all_fail-fas)。 t_behaviour) 無効なベースURLがある場合は、すでに作成した関数を使用して2回呼び出す代わりに、 'Promise.all'を使用することはできません。ベースURLに対して1回、最初のリクエストのレスポンスが「200」の場合1回 これが役立つ場合は、アップホート/回答を忘れないように:) – AbhinavD

関連する問題