2017-05-06 76 views
0

我試圖通過網站進行分頁,其中爲了請求下一頁,需要當前頁面上的信息。調用可變數量的互相依賴的異步函數

function paginateSite(numPages, cb) { 
    var stringToGetToNextPage = '' 
    for (var i = 0; i < numPages; i++) { 
     (function(i, stringToGetToNextPage) { 
      request({ 
       url: 'http://website.com', 
       qs: { 
        nextPage: stringToGetToNextPage 
       } 
      }, 
      function(err, res, body) { 
       body_json = JSON.parse(body) 
       console.log(body_json.stringToGetToNextPage) 
      }) 
     })(i, stringToGetToNextPage) 
    } 
} 

正如你所看到的,我無法在匿名函數之外設置stringToGetToNextPage。我查看了異步庫文檔,但找不到解決我的問題的任何內容。

有沒有人遇到過這個問題?這似乎是異步範例沒有一個乾淨的解決方案的情況。

編輯:問題#2,有沒有想到的方法來做到這一點沒有遞歸?對於小例子遞歸是好的,但現在我有一個可以在不發出警告的情況下終止程序(並且消耗內存)的計算器案例。

回答

1

遞歸就是這樣做的方法。

首先,分解出一個函數來獲取單頁:

function requestPage(stringToGetToNextPage, callback) { 
    request({ 
     url: 'http://website.com', 
     qs: { 
      nextPage: stringToGetToNextPage 
     } 
    }, function(err, res, body) { 
     if (err) { callback(err); } 
     else { callback(null, JSON.parse(body)); } 
    }); 
} 

然後,使能遞歸調用自身獲得每個連續頁面的函數:

function requestAllPages(stringToGetToNextPage, callback) { 
    requestPage(stringToGetToNextPage, function (err, page) { 
     if (err) { callback(err); } 
     else if (page && page.stringToGetToNextPage) { 
      requestAllPages(page.stringToGetToNextPage, callback); 
     } 
     else { callback(); } 
    }); 
} 

然後踢它所有關:

requestAllPages(null, function() { 
    console.log('Done!'); 
}); 

編輯如果你確實想分頁的頁面,而不是去結束一個具體的數字,你可以完成與一個小的修改,以requestAllPages

function requestPages(numPages, stringToGetToNextPage, callback) { 
    if (numPages <= 0) { callback(); return; } 

    requestPage(stringToGetToNextPage, function (err, page) { 
     if (err) { callback(err); } 
     else if (page && page.stringToGetToNextPage) { 
      requestPages(numPages - 1, page.stringToGetToNextPage, callback); 
     } 
     else { callback(); } 
    }); 
} 

requestPages(20, null, function() { 
    console.log('Done!'); 
}); 
+0

有沒有辦法做到這一點沒有遞歸? (見編輯) –

+0

@JacksonDarrow我想不到沒有遞歸的方法,但是你對堆棧溢出和內存使用過多的擔心是沒有根據的。由於這些調用是異步的,它們不會共享相同的堆棧,並且我的代碼被寫入,所以在任何給定的時間內,每個相應函數最多隻能調用一次。 – JLRishe

1

寫遞歸函數。

function get_page(next_page_number, last_page_number, string_needed, callback) { 

    request(
     { 
      url: 'http://website.com', 
      qs: { 
       nextPage: string_needed 
      } 
     }, 
     function(err, res, body) { 
      // NB: Bad variable name. `body` is JSON. `body_json` won't be. 
      var body_json = JSON.parse(body); 

      if (next_page_number == last_page_number) { 
       callback(body_json); 
      } else { 
       get_page(
        next_page_number + 1, 
        last_page_number, 
        body_json.stringToGetToNextPage, 
        callback 
       ); 
      } 
     } 
    ); 

} 

get_page(1, 27, "", function (body_json) { console.log(body_json); }); 
+0

有沒有辦法做到這一點沒有遞歸? (見編輯) –