详解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 相关文章推荐
Json对象与Json字符串互转(4种转换方式)
Mar 27 Javascript
jQuery 淡出一个图像到另一个图像的实现代码
Jun 12 Javascript
通过正则表达式实现表单验证是否为中文
Feb 18 Javascript
js 获取、清空input type="file"的值示例代码
Feb 19 Javascript
jQuery判断复选框是否勾选的原理及示例
May 21 Javascript
JavaScript学习笔记之Function对象
Jan 22 Javascript
以Python代码实例展示kNN算法的实际运用
Oct 26 Javascript
用jquery快速解决IE输入框不能输入的问题
Oct 04 Javascript
Javascript仿京东放大镜的效果
Mar 01 Javascript
Vue网页html转换PDF(最低兼容ie10)的思路详解
Aug 24 Javascript
在vscode中统一vue编码风格的方法
Feb 22 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
May 05 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
将兴奋、喜悦和坎加斯带到戴安娜:亚马逊公主
2020/03/03 欧美动漫
Windows下的PHP5.0安装配制详解
2006/09/05 PHP
一步一步学习PHP(8) php 数组
2010/03/05 PHP
PHP自动选择 连接本地还是远程数据库
2010/12/02 PHP
七款最流行的PHP本地服务器分享
2013/02/19 PHP
codeigniter教程之多文件上传使用示例
2014/02/11 PHP
easyui的tabs update正确用法分享
2014/03/21 PHP
JavaScript 事件查询综合
2009/07/13 Javascript
基于mootools 1.3框架下的图片滑动效果代码
2011/04/22 Javascript
js/html光标定位的实现代码
2013/09/23 Javascript
javascript实现树形菜单的方法
2015/07/17 Javascript
js随机生成26个大小写字母
2016/02/12 Javascript
最全的Javascript编码规范(推荐)
2016/06/22 Javascript
AngularJs  E2E Testing 详解
2016/09/02 Javascript
javascript this详细介绍
2016/09/19 Javascript
jQuery获取this当前对象子元素对象的方法
2016/11/29 Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
2016/12/23 Javascript
5分钟学会Vue动画效果(小结)
2018/07/21 Javascript
vue+element实现打印页面功能
2019/05/20 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
2019/05/28 Javascript
js实现经典贪吃蛇小游戏
2020/03/19 Javascript
vue-cli4项目开启eslint保存时自动格式问题
2020/07/13 Javascript
[53:13]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-GAMING
2014/05/22 DOTA
python读文件逐行处理的示例代码分享
2013/12/27 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
Python简单基础小程序的实例代码
2019/04/28 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
2019/08/26 Python
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
HTML5 canvas基本绘图之绘制矩形
2016/06/27 HTML / CSS
监理员的岗位职责
2013/11/13 职场文书
优秀毕业生的求职信
2014/07/21 职场文书
房屋过户委托书范本
2014/10/07 职场文书
公司欠款证明
2015/06/24 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书
分享15个Webpack实用的插件!!!
2021/03/31 Javascript
Appium中scroll和drag_and_drop根据元素位置滑动
2022/02/15 Python