Javascript 创建异步forEach()';

Javascript 创建异步forEach()';,javascript,asynchronous,xmlhttprequest,Javascript,Asynchronous,Xmlhttprequest,我目前正在编写一个脚本,该脚本将检查页面的所有链接,并突出显示任何断开的链接。同时,这不是一项主要任务,但我才刚刚开始使用Asynch,因此非常感谢对我的代码的任何帮助 var size = 0; var itemsProcessed = 0; console.log("Size: " + size); function linkCheck() { var body = document.querySelectorAll("*"); var checker = Array.from($

我目前正在编写一个脚本,该脚本将检查页面的所有链接,并突出显示任何断开的链接。同时,这不是一项主要任务,但我才刚刚开始使用Asynch,因此非常感谢对我的代码的任何帮助

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完成时遇到了麻烦,但是如果您有任何建议,或者我可以做些什么来让问题更清楚,请随时离开帖子


谢谢大家

如果您需要等待大量请求一个接一个地运行,并在它们完成后执行某些操作,您应该使用
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
});

如前所述,使用XMLHttpRequest并不有趣。下面是一个利用jQuery的完整示例。虽然对承诺进行研究肯定是一个好主意,但对于初学者来说,首先在工作中看到它可能会更好

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()
函数完成后的稍后时间点异步执行

来自服务器的响应到达后,将执行为
成功
列出的函数或为
错误
属性列出的函数,并且在这两种情况下,都会执行
完成
函数


要记住的要点是:如果您定义了任何类型的
send
函数,那么原始函数将继续执行,而不等待答案。如果您想在响应出现时执行某些操作,则必须在闭包中定义它。

使用
document.querySelectorAll('a');'或
$('a')`获取所有锚。还要决定是否要使用jQuery。如果你是,用它做任何事,你会更快乐。还要注意,ajax(
XMLHttpRequest
)是异步的,因此当您检查它时,
req.status
不一定是正确的。仅仅因为我不熟悉这一点,我如何让它等到req.status加载后再检查它?另外,在调用colorUp()之前,如何使forEach部分异步?感谢您的回复,Mike。您需要对Promises和名为
Promise.all
的函数进行一些研究。如果您使用jQuery的
$.ajax
方法,会更容易一些。否则,您必须使
XMLHttpRequest
与承诺一起工作,这不是一项小任务。不过,你可能会找到一个为你做这件事的图书馆。基本上,研究,研究:)。可能重复