Nodejs: 不借助框架,如何最简单有效的实现异步编程 [简约有理]

本文探讨利用原生机制,来最快速简单的实现异步事件流。这个傻瓜化的宗旨,是来自要面对的很实际的问题:

事件1 → 事件2 → 事件3 → 事件4 → 事件5 → 事件6 → ...

运行任务1,当任务1完成时触发事件2运行任务2,当任务2完成时触发事件3运行任务3,...

为了说明所采用的方式,使用一个很家常的任务示例:

→ ‘open’ 打开/home/xiaoming/myread.txt文件,获取文件描述符fd

→ ‘read’ 通过fd,读取该文件内最多90个字节的字符,写入到缓冲区buffer

→ ‘write’ 向缓冲区buffer追加1234567890字符串,通过fd,写回文件100个字符(覆盖)

→ ‘close’ 关闭文件描述符fd

→ ‘error’ 期间发生错误,打印错误

→ ‘done’ 全部完成,打印’Open Read Write Close ok.’

以上每个任务都是异步的,上一个完成运行下一个。
以下是源代码,不言自明。

  • 为了举例方便,这部分代码并不算完整,比如字节读写检查,错误释放fd…并未加入
  • 使用这个原生方式,可以使你最快速的上手异步事件编程
  • new (require('events').EventEmitter)()可以创建一个nodejs事件对象,拥有on, emit等事件管理方法,详细内容可以查看文档
  • on(事件类型, callback)
  • emit(事件类型, 参数1, 参数2, 参数3, ...)
  • Buffer是nodejs读写数据的内存缓冲区的一个抽象,一种表示方式
  • 缓冲区?向操作系统内存申请一片区域,用来存放数据,每隔一段时间,或者强制调用系统fsync(),将内存中的数据写到磁盘

var myemitter = new (require('events').EventEmitter)(),
    fs        = require('fs'),
    filepath  = '/home/xiaoming/myread.txt',
    buflen    = 100,
    buffer    = new Buffer(buflen);

myemitter
    .on('open', function () {
        fs.open(filepath, 'a+', function (err, fd) {
            if (err)
                myemitter.emit('error', 'open', err);
            else
                myemitter.emit('read', fd);
        });
    })
    .on('read', function (fd) { 
        fs.read(fd, buffer, 0, buflen - 10, 0, function (err, bytesRead, buffer) {
            if (err)
                myemitter.emit('error', 'read', err);
            else
                myemitter.emit('write', fd);
        });
    })
    .on('write', function (fd) {
        buffer.write('1234567890', buflen - 10);
        fs.write(fd, buffer, 0, buflen, 0, function (err, written, buffer) {
            if (err)
                myemitter.emit('error', 'write', err);
            else
                myemitter.emit('close', fd);
        });
    })
    .on('close', function (fd) {
        fs.close(fd, function (err) {
            if (err)
                myemitter.emit('error', 'close', err);
            else
                myemitter.emit('done');
        })
    })
    .on('error', function (type, err) {
        console.log('Has some error. type: "%s", error: %j.', type, err);
    })
    .on('done', function () {
        console.log('Open Read Write Close ok.');
    })
    .emit('open')
    ;

    原文作者:Tulayang
    原文地址: https://www.jianshu.com/p/54d7bfe5eb2e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞