如果訂單很重要,而且您的清單很長,並且較晚找到未訪問鏈接的可能性很高,那麼最好的方法就是基本上做您正在做的事情。這是來自流行的async
庫的forEachSeries
實現。
async.forEachSeries = function (arr, iterator, callback) {
callback = callback || function() {};
if (!arr.length) {
return callback();
}
var completed = 0;
var iterate = function() {
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function() {};
}
else {
completed += 1;
if (completed === arr.length) {
callback(null);
}
else {
iterate();
}
}
});
};
iterate();
};
你會看到你已經開始實現的相同的遞歸模式。另一種選擇是將它們全部平行並在追回時跟蹤它們。只要列表中的第一個項目以未訪問的方式返回,您可以立即退出。注意:下面的代碼是未經測試...
var urls = [a,b,c,d],
unvisitedUrls = [],
count = urls.length,
done = false;
var checkUrl = function(d) {
var url = d;
return function(visitItems) {
if (done) return;
count--;
if (visitItems && visitItems.length > 0) {
unvisitedUrls.push(url);
}
else {
urls.splice(urls.indexOf(url)); // remove the visited url
}
if(unvisitedUrls.indexOf(urls[0]) > -1 || count === 0) {
done = true;
// done checking urls, urls[0] is the winner
}
}
}
urls.forEach(function(d) { chrome.history.getVisits(d, checkUrl(d)); });
如果你的列表是數以百萬計的項目長,那麼你可以通過他們分批,而不是一次全部迭代。以下是使用在https://github.com/caolan/async處找到的async
庫的示例。
var checkUrl = function(url, cb) {
chrome.history.getVisits(url, function(itemVisits) {
if (done) return cb();
count--;
if (visitItems && visitItems.length > 0) {
unvisitedUrls.push(url);
}
else {
urls.splice(urls.indexOf(url)); // remove the visited url
}
if(unvisitedUrls.indexOf(urls[0]) > -1 || count === 0) {
done = true;
// done checking urls, urls[0] is the winner
}
cb();
}
};
async.forEachLimit(urls, 50, checkUrl, function(err) { doSomethingWithWinner(); });
因此,這將檢查(可能長)列表中的每個URL。你什麼時候找到哪一個是_first_?你想如何,直到檢查之前的所有內容都被檢查過,以便你知道它確實是第一個? – Chuck 2012-10-23 03:43:47
列表多長時間?你首先考慮什麼?首先根據您的原始URL列表? – Bill 2012-10-23 03:45:36
是的 - 原始問題說我想查找列表中的第一個未訪問的URL。同樣,它表示擔心遞歸方法會導致堆棧溢出(因此,一個大列表) – Chuck 2012-10-23 03:47:14