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

 更新时间:2017年05月04日 08:27:51   作者:ZhangCui  
这篇文章主要介绍了详解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));

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

相关文章

  • Node.js命令行/批处理中如何更改Linux用户密码浅析

    Node.js命令行/批处理中如何更改Linux用户密码浅析

    这篇文章主要给大家介绍了关于Node.js命令行/批处理中如何更改Linux用户密码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • Node中解决接口跨域问题详解

    Node中解决接口跨域问题详解

    在 Node 中编写接口时,我们常常会遇到跨域问题,通过本篇文章,我们来聊聊如何解决 Node 中接口的跨域问题,文中代码示例介绍了非常详细,需要的朋友可以借鉴一下
    2023-04-04
  • Windows系统下Node.js安装以及环境配置的完美教程

    Windows系统下Node.js安装以及环境配置的完美教程

    相信对于很多关注javascript发展的同学来说,nodejs已经不是一个陌生的词眼,下面这篇文章主要给大家介绍了关于Windows系统下Node.js安装以及环境配置的完美教程,需要的朋友可以参考下
    2022-06-06
  • NodeJS基础API搭建服务器详细过程记录

    NodeJS基础API搭建服务器详细过程记录

    本文将以一个超小型web项目,来详细介绍如何使用NodeJS基础的http, fs, path, url等模块提供的API来搭建一个简单的web服务器。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • NodeJS 基于 Dapr 构建云原生微服务应用快速入门教程

    NodeJS 基于 Dapr 构建云原生微服务应用快速入门教程

    Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架,本文重点介绍NodeJS云原生微服务应用,感兴趣的朋友一起看看吧
    2022-07-07
  • Node.js之如何创建TCP服务器端

    Node.js之如何创建TCP服务器端

    这篇文章主要介绍了Node.js之如何创建TCP服务器端问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-09-09
  • 利用node.js爬取指定排名网站的JS引用库详解

    利用node.js爬取指定排名网站的JS引用库详解

    最近在学习node.js爬虫,由于 nodejs 强大的异步特性,让我们可以轻松以异步高并发去爬取网站,下面这篇文章主要给大家介绍了关于利用node.js爬取指定排名网站的JS引用库的相关资料,需要的朋友可以参考下。
    2017-07-07
  • node puppeteer爬虫爬取电影网站及生成pdf文档示例

    node puppeteer爬虫爬取电影网站及生成pdf文档示例

    这篇文章主要介绍了node puppeteer爬虫爬取电影网站及生成pdf文档使用示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 如何利用node转发请求详解

    如何利用node转发请求详解

    这篇文章主要给大家介绍了关于利用node转发请求的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 前端之npm运行时配置文件.npmrc的方法(可用于配置npm淘宝源)

    前端之npm运行时配置文件.npmrc的方法(可用于配置npm淘宝源)

    这篇文章主要给大家介绍了关于前端之npm运行时配置文件.npmrc(可用于配置npm淘宝源)的相关资料,.npmrc 文件是用于配置 npm(Node.js 包管理器)行为的配置文件,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-07-07

最新评论