2017-02-21 52 views
0

我目前正在研究一個腳本,它將檢查頁面的所有鏈接並突出顯示所有損壞的鏈接。同步,這不是一項重大任務,但我只是開始與Asynch合作,所以對我的代碼的任何幫助將非常感謝。製作一個異步forEach()'

var size = 0; 
var itemsProcessed = 0; 
    console.log("Size: " + size); 

function linkCheck() { 
var body = document.querySelectorAll("*"); 
var checker = Array.from($(body).filter("a")); 
size = (Object.keys(checker).length); 

    console.log("Size: " + size); 
var list; 

checker.forEach(function (anchor) { 
    var link = $(anchor).attr("href"); 
    itemsProcessed++; 
    console.log("Items: " + itemsProcessed); 
    if (itemsProcessed == size) { 
     colorUp(list); 
    } 
    var req = new XMLHttpRequest(); 
    req.open('HEAD', $(checker).attr("href"), true); 
    itemsProcessed++; 
    try { 
     req.send(null); 
    } catch (e) { 
     console.log("ERROR"); 
     return true; 
    } 
    console.log(req.status); 
    var data = (req.status !== 200); 
    if (data) { 
     //console.log("Added to List") 
      list += data; 
    } 
    console.log(link, data); 
}); 
} 

function colorUp(list) { 
console.log("DONE"); 
$(list).css({ 
    "border": "3px solid #ffb700", 
    "background": "repeating-linear-gradient(135deg, #FFE0B2, #FFE0B2 5px, #ffffff 5px, #ffffff 10px)" 
}); 
} 


linkCheck(); 

目前,我無法等待對foreach完成,但如果您有任何建議,或任何我可以做更清楚的問題,隨時離開後!

謝謝你們

+0

使用'document.querySelectorAll('a');'或$('a')'來獲得所有錨點。還要決定你是否要使用jQuery。如果你是,用它來做任何事情,你會變得更加快樂。還要注意,ajax('XMLHttpRequuest')是異步的,所以'req.status'在檢查時不一定是正確的。 –

+0

僅僅因爲我不熟悉這個,我怎麼才能讓它等到req.status被加載之前我檢查它?另外,如何在調用colorUp()之前使forEach部分異步? 謝謝你回覆Mike。 – Gwinert

+1

你會想對Promises和名爲'Promise.all'的函數做一些研究。如果你使用jQuery的'$ .ajax'方法,那會更容易一些。否則,你將不得不使用'XMLHttpRequest'來承諾,這是不小的任務。你或許可以找到一個圖書館,但它爲你做。基本上,研究,研究,研究:)。 –

回答

0

如果您需要等待一些要求來運行一個又一個,做一些事情後,他們完成你應該使用reduce陣列方法。

checker.reduce((promise, anchor) => { 
    return promise.then(() => $.ajax({type: "HEAD", url: $(anchor).attr("href")})); 
}, $.Deferred().resolve()).then(responseFromLastRequest => { 
    // Do your stuff here  
}); 

或者,如果你不關心請求的順序,你可以同時運行它們:

$.when.apply($, checker.map(anchor => { 
    return $.ajax({type: "HEAD", url: $(anchor).attr("href")}); 
})).then(() => { 
    // Do your stuff here 
}); 
0

正如有人說,使用XMLHttpRequest工作不好玩。這是一個利用jQuery的完整示例。雖然對Promise進行研究當然是一個好主意,但首先看到Promise對初學者來說可能會更好。

function linkCheck() { 
    var itemsProcessed = 0; 

    var $checker = $('a'); 
    var size = $checker.length; 
    console.log("Size: " + size); 

    var $list = $(); 

    $checker.each(function (anchor) { 
     var link = $(anchor).attr("href"); 
     itemsProcessed++; 
     $.ajax(link, { 
      type: 'HEAD', 
      success: function (response, status, xhr) { 
       var data = (req.status !== 200); 
       if (data) { 
        $list.pushStack([anchor]); 
       } 
       console.log(link, data); 
      }, 
      error: function (xhr, err) { 
       console.log("ERROR"); 
      }, 
      complete: function() { 
       console.log(req.status); 
       console.log("Items: " + itemsProcessed); 
       if (itemsProcessed == size) { 
        colorUp(); 
       } 
      } 
     }); 
    }); 
} 

function colorUp() { 

    console.log("DONE"); 
    $(list).css({ 
     "border": "3px solid #ffb700", 
     "background": "repeating-linear-gradient(135deg, #FFE0B2, #FFE0B2 5px, #ffffff 5px, #ffffff 10px)" 
    }); 
} 


linkCheck(); 

$.ajax(url, settings)函數採用作爲第二個參數即撥轉「等待響應」處理的對象。它定義了一系列函數,在linkCheck()函數完成之後的某個時間點將被異步執行。

在服務器的響應到達後,將執行success列出的功能或error屬性中列出的功能,並且在兩種情況下都會執行complete函數。

要記住的要點是:如果您定義了任何種類的send函數,原始函數將繼續執行而不等待答案。如果你想在響應發生時做些什麼,你必須在閉包中定義它。