zoukankan      html  css  js  c++  java
  • 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("
    ");
            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("
    ");
                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));
  • 相关阅读:
    python 数字格式化
    Python字符串
    Nginx 深入-动静分离, 静态资源css, js 前端请求404问题
    Spring colud gateway 源码小计
    Nginx 场景应用
    Nginx valid_referer 防盗链
    Nginx 基础
    JNI 从零开始一次DEMO调用 IDEA 2018.2.5 + visual studio 2019
    Bitmap 图片说明
    HP激光打印机解密
  • 原文地址:https://www.cnblogs.com/zczhangcui/p/6801609.html
Copyright © 2011-2022 走看看