详解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 相关文章推荐
javascript css float属性的特殊写法
Nov 13 Javascript
JavaScript实现点击按钮后变灰避免多次重复提交
Jul 15 Javascript
利用JavaScript的AngularJS库制作电子名片的方法
Jun 18 Javascript
纯javascript实现的小游戏《Flappy Pig》实例
Jul 27 Javascript
jquery调整表格行tr上下顺序实例讲解
Jan 09 Javascript
JavaScript中匿名函数的用法及优缺点详解
Jun 01 Javascript
给vue项目添加ESLint的详细步骤
Sep 29 Javascript
利用百度地图API获取当前位置信息的实例
Nov 06 Javascript
vue进行图片的预加载watch用法实例讲解
Feb 07 Javascript
Node.js利用console输出日志文件的方法示例
Apr 27 Javascript
vue组件内部引入外部js文件的方法
Jan 18 Javascript
解决Vue keep-alive 调用 $destory() 页面不再被缓存的情况
Oct 30 Javascript
纯原生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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
is_uploaded_file函数引发的不能上传文件问题
2013/10/29 PHP
PHP类中的魔术方法(Magic Method)简明总结
2014/07/08 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
jquery操作checked属性以及disabled属性的多种方法
2014/06/20 Javascript
jQuery制作简单柱状图实例
2015/01/28 Javascript
jQuery插件实现静态HTML验证码校验
2015/11/06 Javascript
jQuery+CSS3实现仿花瓣网固定顶部位置带悬浮效果的导航菜单
2016/09/21 Javascript
详解vue-router 命名路由和命名视图
2018/06/01 Javascript
JavaScript数组基于交换的排序示例【冒泡排序】
2018/07/21 Javascript
vuejs2.0运用原生js实现简单拖拽元素功能
2020/08/21 Javascript
JS中的算法与数据结构之二叉查找树(Binary Sort Tree)实例详解
2019/08/16 Javascript
微信小程序实现导航栏和内容上下联动功能代码
2020/06/29 Javascript
mpvue 项目初始化及实现授权登录的实现方法
2020/07/20 Javascript
Python脚本实现集群检测和管理功能
2015/03/06 Python
python检测某个变量是否有定义的方法
2015/05/20 Python
python opencv旋转图像(保持图像不被裁减)
2018/07/26 Python
在python中pandas的series合并方法
2018/11/12 Python
keras 特征图可视化实例(中间层)
2020/01/24 Python
Anaconda使用IDLE的实现示例
2020/09/23 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
HTML5之消息通知的使用(Web Notification)
2018/10/30 HTML / CSS
财务会计专业毕业生自荐信
2013/10/02 职场文书
个人求职信范文分享
2014/01/06 职场文书
党校学习自我鉴定
2014/02/24 职场文书
《果园机器人》教学反思
2014/04/13 职场文书
司法助理专业自荐书
2014/06/13 职场文书
我的中国梦演讲稿800字
2014/08/19 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
2014年世界艾滋病日宣传活动总结
2014/11/18 职场文书
正规借条模板
2015/05/26 职场文书
2015年党小组工作总结
2015/05/26 职场文书
运动会3000米加油稿
2015/07/21 职场文书
解决hive中导入text文件遇到的坑
2021/04/07 Python