当前位置: 首页 > 编程笔记 >

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

叶富
2023-03-14
本文向大家介绍详解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("\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));

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Javascript异步流程控制之串行执行详解,包括了Javascript异步流程控制之串行执行详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要讲一下如何串行执行一组异步任务,例如有下面几个任务,在这里我们用setTimeout模拟一个异步任务: 直接运行 是达不到顺序执行A,B,C 的三个任务的效果的。 首先我们看一下最传统的做法,通过回调的方式在一个任务执行完成之后调用

  • 本文向大家介绍Python中的流程控制详解,包括了Python中的流程控制详解的使用技巧和注意事项,需要的朋友参考一下 流程控制无非就是if else之类的控制语句,今天我们来看一下Python中的流程控制会有什么不太一样的地方。 while语句 python中的while语句和其他语言没有什么不一样,我使用while语句来编写一个斐波拉赫数列: if 语句 python中的 if 可以和 eli

  • 本文向大家介绍详解Python流程控制语句,包括了详解Python流程控制语句的使用技巧和注意事项,需要的朋友参考一下 流程控制 流程:代码执行的过程 控制:对代码执行过程的把控 三大结构 顺序结构:代码默认从上到下,依次执行 分支结构:单项分支,双向分支,多项分支,巢状分支 循环结构:while循环和for循环 单项分支 语句: if 条件表达式:     code1     code2 当条件

  • 本文向大家介绍Swift教程之控制流详解,包括了Swift教程之控制流详解的使用技巧和注意事项,需要的朋友参考一下 Swift提供了所有C语言中相似的控制流结构。包括for和while循环;if和switch条件语句;break和continue跳转语句等。 Swift还加入了for-in循环语句,让编程人员可以在遍历数组,字典,范围,字符串或者其它序列时更加便捷。 相对于C语言,Swift中sw

  • 本文向大家介绍python学习 流程控制语句详解,包括了python学习 流程控制语句详解的使用技巧和注意事项,需要的朋友参考一下 ###################### 分支语句 python3.5 ################ #代码的缩进格式很重要 建议4个空格来控制 #根据逻辑值(True,Flase)判断程序的运行方向 # Ture:表示非空的量(String,tuple元组

  • 本文向大家介绍C语言流程控制之switch语句详解,包括了C语言流程控制之switch语句详解的使用技巧和注意事项,需要的朋友参考一下 switch语句结构 表达式是选择条件,可以是单个变量也可以是组合的表达式,其最终的结果必须是一整数值,{}内的所有内容是switch语句的主体,内含多个case分支,判断值必须是一常量,case分支根据判断值标识条件选择的入口;break语句用于退出switch