node.js学习笔记--HTTP之Promise重写小爬虫

2024-01-28 16:18

本文主要是介绍node.js学习笔记--HTTP之Promise重写小爬虫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注:此博客是在学习进击Node.js基础(一)这门课程时的学习笔记,感谢Scott老师的课程。

一、使用Promise处理异步、嵌套

1. 用传统的回调来按顺序执行小球动画

<!doctype>
<html>
<head><title>Promise animation</title><style>.ball{width: 40px;height:40px;border-radius: 20px;}.ball1{background: red;}.ball2{background: yellow;}.ball3{background: green;}</style><!-- 引用bluebird这个库来使用promise函数,bluebird被我下在了Desktop的上一级,administrator文件夹里 --><script scr="C:\Users\Administrator\node_modules\bluebird\js\browser\bluebird.js"></script>
</head>
<body><div class='ball ball1' style="margin-left: 0;"></div><div class='ball ball2' style="margin-left: 0;"></div><div class='ball ball3' style="margin-left: 0;"></div><script>var ball1 = document.querySelector('.ball1')var ball2 = document.querySelector('.ball2')var ball3 = document.querySelector('.ball3')console.log(ball1)function animate(ball, distance, callback){setTimeout(function(){var marginLeft = parseInt(ball.style.marginLeft, 10)//如果小球到达目标点,即动画已经执行完毕,就执行回调函数if(marginLeft === distance){callback && callback()}else{if(marginLeft < distance){  //球在左侧,就往右移marginLeft++}else{marginLeft--}ball.style.marginLeft = marginLeftanimate(ball, distance, callback)  //继续调用自身animate,不断重复调整小球位置,直到移到目标位置}}, 13)   //设定间隔多少时间执行函数,13毫秒一次}       //传统的按顺序执行调用函数//第一个球向右移动100像素,然后执行移动第二个球,第二个球向右移动200像素,然后执行移动第三个球...animate(ball1, 100, function(){animate(ball2, 200, function(){animate(ball3, 300, function(){animate(ball3, 150, function(){animate(ball2, 150, function(){animate(ball1, 150, function(){//})})})})})})</script>
</body>
</html>

效果:
这里写图片描述
2.用Promise方法重写一遍同样的按顺序执行小球动画

调用bluebird里的promise函数,和上面的逻辑一样,但是函数申明的方式不一样。而且对比上面的嵌套写法,如果想要更改小球的顺序或者加其他动作,上面的写法就很麻烦。相比,用Promise,每个动作的顺序关系就是线性的。一个Promise是一个带有.then()方法的对象,是异步编程的抽象。

<!doctype>
<html>
<head><title>Promise animation</title><style>.ball{width: 40px;height:40px;border-radius: 20px;}.ball1{background: red;}.ball2{background: yellow;}.ball3{background: green;}</style><!-- 引用bluebird这个库来使用promise函数,bluebird被我下在了Desktop的上一级,administrator文件夹里 --><script scr="C:\Users\Administrator\node_modules\bluebird\js\browser\bluebird.js"></script>
</head>
<body><div class='ball ball1' style="margin-left: 0;"></div><div class='ball ball2' style="margin-left: 0;"></div><div class='ball ball3' style="margin-left: 0;"></div><script>var ball1 = document.querySelector('.ball1')var ball2 = document.querySelector('.ball2')var ball3 = document.querySelector('.ball3')console.log(ball1)var Promise = window.Promise //不过现在好像原生支持Promise,不需要引入库了function promiseAnimate(ball, distance){return new Promise(function(resolve, reject){function _animate(){  //下划线表示_animate是私有函数setTimeout(function(){  //定时器var marginLeft = parseInt(ball.style.marginLeft, 10)if(marginLeft === distance){resolve()  //如果小球到达目标点,即动画已经执行完毕,就执行回调函数}else{if(marginLeft < distance){  //球在左侧,就往右移marginLeft++}else{marginLeft--}ball.style.marginLeft = marginLeft + 'px'_animate() //调用自身}}, 13)   //设定间隔多少时间执行函数,13毫秒一次}_animate() //启动第一次调用})}//原理: .then()函数总是返回一个新的Promise,then()里可放两个参数,第一个为前面函数执行成功的返回函数,第二个为执行不成功的返回函数promiseAnimate(ball1, 100).then(function(){return promiseAnimate(ball2, 200)}).then(function(){return promiseAnimate(ball3, 300)}).then(function(){return promiseAnimate(ball3, 150)}).then(function(){return promiseAnimate(ball2, 150)}).then(function(){return promiseAnimate(ball1, 150)})</script>
</body>
</html>

二、用Promise重写小爬虫

重写上一篇里的node.js学习笔记–HTTP之小爬虫。

//用Promise来重构小爬虫,去除之前的回调
var http = require('http')
var Promise = require('Promise') //新版本的nodejs可以直接引用Promise了
var cheerio = require('cheerio')   //一个像JQuery语法一样可以提供快捷检索的库
var url = 'http://www.imooc.com/learn/348'
var baseUrl = 'http://www.imooc.com/learn/'function filterChapters(html){var $ = cheerio.load(html)var chapters = $('.mod-chapters')//网页上的数据结构// courseData = {//      [{//      chapterTitle: '',//      videos: [//          title: '',//          id: ''//      ]//      }]// }var courseData = []//对每一章进行遍历chapters.each(function(item){var chapter = $(this) //拿到每个单独的章节var chapterTitle = chapter.find('strong').text()var videos =  chapter.find('.video').children('li')var chapterData = {chapterTitle: chapterTitle,videos: []} //组装对象//对videos进行遍历videos.each(function(item){var video = $(this).find('.J-media-item') //拿到每个单独的video里的classvar videosTitle = video.text() //返回该元素下的所有文本内容var id =  video.attr('href').split('video/')[1]  //要拿到href链接里video/后的内容即视频idchapterData.videos.push({title: videosTitle,id: id})})courseData.push(chapterData) //把拿好的章节数据放进数组})return courseData
}function printCourseInfo(courseData){courseData.forEach(function(item){  //对courseData这个数组进行遍历var chapterTitle = item.chapterTitleconsole.log(chapterTitle + '\n')item.videos.forEach(function(video){console.log('(' + video.id + ')' + video.title + '\n')})})
}function getPageAsync(url){return new Promise(function(resolve, reject){console.log('正在爬取 ' + url)http.get(url, function(res){var html = ''res.on('data', function(data){html += data})  //收到数据data时这个事件就会不断被触发,html字符串就不断累加res.on('end',function(){resolve(html)//var courseData = filterChapters(html) //原来的回调写法//printCourseInfo(courseData)})  //end事件}).on('error', function(){reject(e)console.log('获取课程数据出错')})//http.get还可以注册error事件,当出现异常时能捕捉错误})
}//可同步爬取多个课程
var fetchCourseaArray = []videoIds.forEach(function(id){fetchCourseaArray.push(getPageAsync(baseUrl + id))
})Promise.all(fetchCourseaArray).then(function(pages){var coursesData = []pages.forEach(function(html){var courses = filterChapters(html) //解析htmlcoursesData.push(courses)})})

这篇关于node.js学习笔记--HTTP之Promise重写小爬虫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/654137

相关文章

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no