内容主要来源:吴海星译,《Node.js实战》。

串行任务:需要一个接着一个坐的任务叫做串行任务。

可以使用回调的方式让几个异步任务按顺序执行,但如果任务过多,必须组织一下,否则过多的回调嵌套会把代码搞得很乱。

为了用串行化流程控制让几个异步任务按顺序执行,需要先把这些任务按预期的执行顺序放到一个数组中,这个数组将起到队列的作用:完成一个任务后按顺序从数组中取出下一个。

数组中的每个任务都是一个函数。任务完成后应该调用一个处理器函数,告诉它错误状态和结果。

为了演示如何实现串行化流程控制,我们准备做个小程序,让它从一个随机选择的RSS预定源中获取一篇文章的标题和URL,并显示出来。

需要从npm存储苦衷下载两个辅助模块,在命令行中(以mac系统为例)输入以下命令:

mkdir random_story
cd random_story
npm install request
npm install htmlparser

request模块是个简化的HTTP客户端,可以获取RSS数据。htmlparser模块能够把原始的RSS数据转换成JavaScript数据结构。

在新目录下创建一个random_story.js文件,包含以下代码:

var fs = require('fs');
var request = require('request');
var htmlparser = require('htmlparser');
var configFilename = './rss_feeds.txt';
//确保包含RSS订阅列表的文件存在
function checkForRSSFile() {
fs.exists(configFilename, function(exists) {
if (!exists) {
return next(new Error('Missing RSS file: ' + configFilename));
}
next(null, configFilename);
});
}
//读取并解析包含RSS订阅列表的文件
function readRSSFile(configFilename) {
fs.readFile(configFilename, function(err, feedList) {
if (err) {
return next(err);
} feedList = feedList.toString().replace(/^\s+|\s+$/g, '').split("\n");
var random = Math.floor(Math.random()*feedList.length);
next(null, feedList[random]);
});
}
//向预定源发送HTTP请求以获取数据
function downloadRSSFeed(feedUrl) {
request({uri: feedUrl}, function(err, res, body) {
if (err) {
return next(err);
}
if (res.statusCode !== 200) {
return next(new Error('Abnormal response status code'));
}
next(null, body);
});
}
//解析到一个条目数组中
function parseRSSFeed(rss) {
var handler = new htmlparser.RssHandler();
var parser = new htmlparser.Parser(handler);
parser.parseComplete(rss);
if (!handler.dom.items.length) {
return next(new Error('No RSS items found.'));
}
var item = handler.dom.items.shift();
console.log(item.title);
console.log(item.link);
} var tasks = [
checkForRSSFile,
readRSSFile,
downloadRSSFeed,
parseRSSFeed
];
function next(err, result) {
if (err) {
throw err;
}
var currentTask = tasks.shift();
if (currentTask) {
currentTask(result);
}
}
//开始执行串行化任务
next();

在试用这个程序之前,现在程序脚本所在的目录下创建一个rss_feeds.txt文件。这里只包含了一条预定源信息:

http://dave.smallpict.com/rss.xml

之后执行脚本:

node random_story.js

返回信息如上图。成功实现了一个串行化流程控制。

[async/await形式的串行化流程控制]

之后将源代码改写了一下,改写成ES7的async/await形式。水平有限,如有错误请指出!

let fs = require('fs');
let request = require('request');
let htmlparser = require('htmlparser');
let configFilename = './rss_feeds.txt'; function checkForRSSFile() {
return new Promise((resolve, reject) => {
fs.exists(configFilename, (exists) => {
if (!exists) {
reject(new Error('Missing RSS file: ' + configFilename));
}
resolve();
});
});
} function readRSSFile(configFilename) {
return new Promise((resolve, reject) => {
fs.readFile(configFilename, (err, feedList) => {
if (err) {
reject(err);
}
feedList = feedList.toString().replace(/^\s+|\s+$/g, '').split("\n");
let random = Math.floor(Math.random()*feedList.length);
resolve(feedList[random]);
});
});
} function downloadRSSFeed(feedUrl) {
return new Promise((resolve, reject) => {
request({uri: feedUrl}, (err, res, body) => {
if (err) {
reject(err);
}
if (res.statusCode !== 200) {
reject(new Error('Abnormal response status code'));
}
resolve(body);
});
});
} function parseRSSFeed(rss) {
let handler = new htmlparser.RssHandler();
let parser = new htmlparser.Parser(handler);
parser.parseComplete(rss);
if (!handler.dom.items.length) {
throw new Error('No RSS items found.');
}
let item = handler.dom.items.shift();
console.log(item.title);
console.log(item.link);
} async function getRSSFeed() {
await checkForRSSFile();
let url = await readRSSFile(configFilename);
let rss = await downloadRSSFeed(url);
return rss;
}
getRSSFeed().then(rss => parseRSSFeed(rss), e => console.log(e));

Node.js-串行化流程控制的更多相关文章

  1. 【Nodejs】使用nimble串行化回调任务

    nodejs的nimble模块可以使我们对回调任务进行串行化,它需要先安装 #npm install nimble 用法也方便,示例代码如下: //========================== ...

  2. 【Java EE 学习 72 下】【数据采集系统第四天】【移动/复制页分析】【使用串行化技术实现深度复制】

    一.移动.复制页的逻辑实现 移动.复制页的功能是在设计调查页面的时候需要实现的功能.规则是如果在同一个调查中的话就是移动,如果是在不同调查中的就是复制. 无论是移动还是复制,都需要注意一个问题,那就是 ...

  3. 【性能诊断】四、单功能场景的性能分析(RedGate,找到同一个客户端的并发请求被串行化问题)

    问题描述: 客户端js连续发起两个异步http请求,请求地址相同,但参数不同:POST http://*.*.*.*/*****/webservice/RESTFulWebService/RESTFu ...

  4. JavaEE 对象的串行化(Serialization)

    什么情况下需要序列化 a)当你想把的内存中的对象写入到硬盘的时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候:再稍微解释一下:a)比如说你的内存不够用了,那计算机就要 ...

  5. MFC用串行化实现文档存储和读取功能

    在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...

  6. Hadoop基础-Apache Avro串行化的与反串行化

    Hadoop基础-Apache Avro串行化的与反串行化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Apache Avro简介 1>.Apache Avro的来源 ...

  7. 关于ORACLE的串行化隔离级别--来自ORACLE概念手册

    为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被 称为串行化处理(serializability)的事务隔离模型(transaction  isolation model).当所有 ...

  8. PHP面向对象04_串行化

    oop04复习 2014-9-3 10:48:45 要点: --1.克隆对象 --2.__toString( ) --3. __call( ) --4.自动加载类 --5.对象串行化 1.克隆对象以及 ...

  9. 【PHP面向对象(OOP)编程入门教程】22.把对象串行化serialize()方法,__sleep()方法,__wakeup()方法

    有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化(也叫序列化), 就像我们现在想把一辆汽车通过轮船运到美国去,因为 ...

随机推荐

  1. Tools - 浏览器Firefox

    简介 http://www.mozilla.org/ 中文官网:http://www.firefox.com.cn/ https://www.mozilla.org/zh-CN/firefox/ Mo ...

  2. 【原创】手动导入SQLServer数据到SQLCE方法

    我找到一个工具,可以很容易把SQLServer里的数据导入到SQLCE: 工具名:Export2SqlCe.exe, 下载路径: http://exportsqlce.codeplex.com/rel ...

  3. Redis学习系列三List列表

    一.简介 Redis中的列表相当于C#中的LinkedList,也就是链表,如果你研究过链表这个数据结构,肯定知道.它的插入和删除是非常快的,但是定位却很慢,因为必须遍历所有的元素,才能找到对应的值, ...

  4. 从学CodeSmith谈程序员学习方法

    一直觉得CodeSmith是个好东西,最近正好有点时间来研究下,其实以前也想学习怎么用,在博客园搜一下有很多介绍CodeSmith的文章,我就收藏过一个写得很详细的http://terrylee.cn ...

  5. JSPatch动态更新APP

    JSPatch,只需在项目中引入极小的引擎,就可以使用JavaScript调用任何Objective-C的原生接口,获得脚本语言的能力:动态更新APP,替换项目原生代码修复bug. 用途 是否有过这样 ...

  6. 第十五章-class类文件结构

    参考博文: (1)关于class的签名Signature (2)关于访问标识 (3)关于Class中的Signature属性 (4)附录1 常量池解析 (5)附录2 方法解析 (6)Class文件结构 ...

  7. CSS3 Drop-Shadows效果制作教程分享

    要求 必备知识 基本了解CSS语法,初步了解CSS3语法知识. 开发环境 Adobe Dreamweaver CS6/Chrome浏览器 演示地址 演示地址 Drop-Shadow效果,其实就是大家熟 ...

  8. linux 文件句柄数查看命令

    当你的服务器在大并发达到极限时,就会报出“too many open files”. 查看线程占句柄数ulimit -a 输出如下:core file size (blocks, -c) 0data ...

  9. Flutter踩坑日记:解除依赖

    Flutter已经融入工程有一段时间了,由于团队人数较少,所以一直没有管和原有工程解依赖的问题,今天有时间正好把这个问题给搞了. 一.分析 首先,直接忽略上一篇<接入现有iOS项目>的所有 ...

  10. Python代码注释应该怎么写?

    https://zhuanlan.zhihu.com/p/22663276?refer=passer http://zh-google-styleguide.readthedocs.io/en/lat ...