详解Node.js串行化流程控制


Posted in Javascript onMay 04, 2017

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

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

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

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

为了演示如何实现串行化流程控制,我们准备做个小程序,让它从一个随机选择的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

详解Node.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));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery Flash/MP3/Video多媒体插件
Jan 18 Javascript
JavaScript 存在陷阱 删除某一区域所有节点
May 10 Javascript
基于jquery的鼠标拖动效果代码
May 30 Javascript
Js与下拉列表处理问题解决
Feb 13 Javascript
JS+Canvas绘制时钟效果
Aug 20 Javascript
jQuery获取剪贴板内容的方法
Jun 16 Javascript
JavaScript中动态向表格添加数据
Jan 24 Javascript
JS回调函数简单用法示例
Feb 09 Javascript
JS生成随机打乱数组的方法示例
Dec 23 Javascript
浅谈Vue组件及组件的注册方法
Aug 24 Javascript
微信小程序新手教程之启动页的重要性
Mar 03 Javascript
Vue实现摇一摇功能(兼容ios13.3以上)
Jan 26 Vue.js
纯原生js实现贪吃蛇游戏
Apr 16 #Javascript
js调用刷新界面的几种方式
May 03 #Javascript
JavaScript中双向数据绑定详解
May 03 #Javascript
Js实现中国公民身份证号码有效性验证实例代码
May 03 #Javascript
Vue原理剖析 实现双向绑定MVVM
May 03 #Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
May 03 #Javascript
Vue实现双向数据绑定
May 03 #Javascript
You might like
UCenter Home二次开发指南
2009/05/28 PHP
PHP冒泡排序算法代码详细解读
2011/07/17 PHP
PHP获取Exif缩略图的方法
2015/07/13 PHP
PHP Echo字符串的连接格式
2016/03/07 PHP
PHP实现对xml的增删改查操作案例分析
2017/05/19 PHP
PHP实现生成推广海报的方法详解
2018/03/14 PHP
javascript 动态table添加colspan\rowspan 参数的方法
2009/07/25 Javascript
仿百度输入框智能提示的js代码
2013/08/22 Javascript
使用js在页面中绘制表格核心代码
2013/09/16 Javascript
jQuery实现新消息在网页标题闪烁提示
2015/06/23 Javascript
JavaScript实现级联菜单的方法
2015/06/29 Javascript
mac下的nodejs环境安装的步骤
2017/05/24 NodeJs
AngularJs 延时器、计时器实例代码
2017/09/16 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
bootstrap table支持高度百分比的实例代码
2018/02/28 Javascript
Vue 父子组件数据传递的四种方式( inheritAttrs + $attrs + $listeners)
2018/05/04 Javascript
vue中关闭eslint的方法分析
2018/08/04 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
处理JavaScript值为undefined的7个小技巧
2020/07/28 Javascript
Python命令启动Web服务器实例详解
2017/02/23 Python
win10下Python3.6安装、配置以及pip安装包教程
2017/10/01 Python
利用Python查看微信共同好友功能的实现代码
2019/04/24 Python
用python写一个定时提醒程序的实现代码
2019/07/22 Python
利用python在大量数据文件下删除某一行的例子
2019/08/21 Python
Python基础之列表常见操作经典实例详解
2020/02/26 Python
python 图像判断,清晰度(明暗),彩色与黑白实例
2020/06/04 Python
Avène雅漾美国官方网站:敏感肌肤护理专家
2016/10/24 全球购物
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
上级检查欢迎词
2014/01/18 职场文书
小学清明节活动总结
2014/07/04 职场文书
学生实习证明范文
2014/09/28 职场文书
2019秋季运动会口号
2019/06/25 职场文书
检讨书之工作不认真
2019/08/14 职场文书
Python 语言实现六大查找算法
2021/06/30 Python
pytorch实现加载保存查看checkpoint文件
2022/07/15 Python