Promise队列应用实例(爬虫)

本文介绍了如何使用Promise和异步队列来实现每隔一秒输出数组中的字符串,以及一个基于Promise的网页爬虫功能。示例中展示了两种Promise队列的实现方式,并在爬虫代码中应用了队列,以按顺序抓取和处理网页链接。此外,代码还包含了处理HTTP响应和错误的情况。
摘要由CSDN通过智能技术生成

每隔一秒输出数组中的一个字符串,直到全部输出完成为止

var arr=["你好","hello","hi","good morning","nice to meet you"];
function run(str){
    //异步输出字符串
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log(str);
            resolve(str);
        },1000);
    });
}
//-----写法一-----
function queue(qs){
    let promise=Promise.resolve();
    qs.forEach((e,i,arr)=>{//这里的foreach可以理解为:将多个then操作直接串联起来,而不是每次替换上一个promise的值
        promise=promise.then(function(val){
            return run(e);
        });
    });
    return promise;
}

//-----写法二-----
function queue(qs){
    return qs.reduce((promise,e)=>{
        return promise.then(function(val){
            return run(e);
        });
    },Promise.resolve());
}

queue(arr).then(()=>{
    console.log("全部输出完成!");
});

队列输出.gif

爬虫代码

<script>
    //这是用Promise.then队列实现的一个网页爬虫功能;
    //data中返回的字段: title:string,url:string,children:[]
    //待优化:添加deep设置探测深度
    function fetch(url) {
        let delayTime = 1000;
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                var xhr = new XMLHttpRequest();
                xhr.open("GET", url, true);
                xhr.responseType = "document";
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === XMLHttpRequest.DONE && xhr.status == 200) {
                        var domTree = xhr.response;
                        var urls = Array.prototype.map.call(domTree.getElementsByTagName("a"), (e, i, arr) => {
                            return e.getAttribute("href");
                        });

                        if (urls.length > 0) {
                            var results = [];
                            queue(urls, results).then(() => {
                                resolve({
                                    title: domTree.title,
                                    status: xhr.status,
                                    url: url,
                                    children: results,
                                });
                            });
                        } else {
                            resolve({
                                title: domTree.title,
                                status: xhr.status,
                                url: url,
                                children: [],
                            });
                        }
                    } else if (xhr.readyState === XMLHttpRequest.DONE && xhr.status != 200) {
                        resolve({
                            title: "错误页面",
                            status: xhr.status,
                            url: url,
                            children: [],
                        });
                    }
                }
                xhr.send();
            }, delayTime);
        });
    }

    function queue(urls, D) {
        return urls.reduce((promise, url) => {
            return promise.then(() => {
                return new Promise((r, j) => {
                    fetch(url).then((data) => {
                        D.push(data);
                        r();
                    });
                });
            });
        }, Promise.resolve());
    }

    fetch(location.href).then((data) => {
        console.log(data);
    });
</script>

pachong.html中有p1、p2、p3三个页面链接
p1中有p11、p12、p13三个链接

页面跳转结构如图

最终打印的页面结构
爬虫请求过程.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT飞牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值