首页 > 编程 > JavaScript > 正文

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

2019-11-19 16:40:15
字体:
来源:转载
供稿:网友

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

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

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

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

为了演示如何实现串行化流程控制,我们准备做个小程序,让它从一个随机选择的RSS预定源中获取一篇文章的标题和URL,并显示出来。

需要从npm存储苦衷下载两个辅助模块,在命令行中(以mac系统为例)输入以下命令:

mkdir random_storycd random_storynpm install requestnpm 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));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表