Node.js-串行化流程控制

内容主要来源:吴海星译,《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));
时间: 2024-08-09 15:06:08

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

Node.js 实现串行化流程控制

为了演示如何实现串行流程控制,我们准备做个小程序,让它从一个随机选择的RSS预定源中获取一片标题和URL,并显示出来. RSS预定源列表放在rss_feeds.txt文件中,内容如下: http://feed.cnblogs.com/blog/u/376823/rss http://lambda-the-ultimate.org/rss.xml 运行程序前我们需要安装两个模块:request模块是个经过简化的HTTP客户端,你可以用它获取RSS数据.htmlparser模块能把原始的RSS数据转

对象的串行化

一.串行化的概念和目的 1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(persistence).对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行化(Serialization) .串行化的主要任务是写出对象实例变量的数值.如果交量是另一对象的引用,则引用的对象也要串行化.这个过程是递归的,串行化可能要涉及一个复杂树结构的单行化,包括

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

问题描述: 客户端js连续发起两个异步http请求,请求地址相同,但参数不同:POST http://*.*.*.*/*****/webservice/RESTFulWebService/RESTFulHandlerForWeb.ashx HTTP/1.1 服务器端第二方法的响应时间明显很长(不正常),在ProcessRequest方法上增加日志后发现,第二个方法的开始时间明显延迟了大约0.5秒 后台跟踪发现累计SQL执行时间不超过50毫秒: 使用log记录应用处理的响应时间(11表示handl

JavaEE 对象的串行化(Serialization)

什么情况下需要序列化 a)当你想把的内存中的对象写入到硬盘的时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候:再稍微解释一下:a)比如说你的内存不够用了,那计算机就要将内存里面的一部分对象暂时的保存到硬盘中,等到要用的时候再读入到内存中,硬盘的那部分存储空间就是所谓的虚拟内存.在比如过你要将某个特定的对象保存到文件中,我隔几天在把它拿出来用,那么这时候就要实现Serializable接口:b)在进行java的Socket编程的时候,你有时候可能要传输某一类的对象

java串行化

一.串行化的概念和目的 1.什么是串行化 对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力,叫作对象的持续性(persistence).对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行化(Serialization) .串行化的主要任务是写出对象实例变量的数值.如果变量是另一对象的引用,则引用的对象也要串行化.这个过程是递归的,串行化可能要涉及一个复杂树结构的单行化,包括

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

为了描述同时执行的多个事务如何实现数据一致性,数据库研究人员定义了被 称为串行化处理(serializability)的事务隔离模型(transaction  isolation model).当所有事务都采取串行化的模式执行时,我们可以认为同一时间只有 一个事务在运行(串行的),而非并发的 以串行化模式对事务进行隔离的效果很好,但在此种模式下应用程序的效率将 大大降低.将并行执行的事务完全隔离意味着即便当前只存在一个对表进行查 询(query)的事务,其他事务 也不能再对此表进行插入(inse

PostgreSQL串行化隔离级别(SSI)的能力与实现

https://zhuanlan.zhihu.com/p/37087894 PostgreSQL9.1是第一个采用Serializable Snapshot Isolation(SSI)实现串行化隔离级别的生产级数据库. 本文的目标是学习与分析SSI的设计思路,以及在PG中的实现与优化.首先介绍了隔离级别以及实现其的两个基本并发控制机制,给出了PG的SI未达到串行化的案例,分析原因并给出直观的解决思路,其次阐述了SSI的技术思路与关键环节,最后就PG内核中SSI的实现与优化思路进行了分析. 1.

PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化)/约束类型/魔术方法小结

  前  言  OOP  学习了好久的PHP,今天来总结一下PHP中的抽象类与抽象方法/静态属性和静态方法/PHP中的单利模式(单态模式)/串行化与反串行化(序列化与反序列化). 1  PHP中的抽象类与抽象方法 1.什么是抽象方法?              没有方法体 {} 的方法,必须使用abstract 关键字修饰.这样的方,我们叫做抽象方法.                    abstract function say(); //    抽象方法 2.什么是抽象类?        

对象的序列化(串行化)分析(一)

对象的序列化(串行化)序列化概念:(1)对象的寿命通常随着生成该对象的程序的终止而终止.有时候,可能需要将对象的状态保存下 来,在需要时再将对象恢复.我们把对象的这种能记录自己的状态以便将来再生的能力.叫作对象的持续性(persistence).对象通过写出描述自己状 态的数值来记录自己 ,这个过程叫对象的串行化(Serialization-连续) .(2)一个对象随着创建而存在,随着程序结束而结束.那 如果我要保存一个对象的状态呢?Java序列化能够将对象的状态写入byte流存储起来,也从其他