2019年1月24日 星期四

pipe

https://www.npmjs.com/package/multipipe
https://github.com/zoubin/streamify-your-node-program

http://www.xiedacon.com/2017/08/11/Node.js%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-pipe%E5%AE%9E%E7%8E%B0/#Node-js%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90-pipe%E5%AE%9E%E7%8E%B0

-----------------------------------------------------------------------

const _ = require("underscore");
require("underscore_extension")(_);

const $path = require("path");
const $fs = require('fs');
const $zlib = require('zlib');

http();

function http() {

    let server = require("http").createServer(async function (req, resp) {

        resp.writeHead(200, {
            'Content-Type': 'image/jpg',
            'content-encoding': 'gzip'
        });


        let _path = $path.resolve(__dirname, './images/plane_1.jpg');

        let reader = $fs.createReadStream(_path);
        reader = reader.pipe($zlib.createGzip());
        await pipe(reader, resp);

        resp.end();
    });
    server.listen(8081);
}

function _error(res) {
    res.writeHead(200, {
        'Content-Type': 'text/html'
    });
    console.log('error...')
    res.end('<h1>error</h1>');
}


function pipe(reader, writer, size) {

    let def = _.deferred();

    reader.on('readable', function () {
        // 採用靜態模式
        console.log('----------readable----------------');
        write();
    });

    reader.on('data', function (chunk) {
        // reader.read() 會進來此
        console.log('on data(%s)', chunk.length);
    });

    writer.on('drain', function () {
        console.log('drain..........');

        let data;

        // 讀取之未讀完的記憶體
        if (!write(true)) {
            return;
        }

        console.log('舊的讀取完');
        reader.resume();
    });

    reader.on('end', function () {
        console.log('end');
        def.resolve();
    });
    //----------------------------

    function write(noPause) {
        console.log('....write')
        while (true) {
            console.log('read(%s)', (noPause ? 'flush' : 'ok'));
            let data = reader.read(size);

            if (data === null) {
                console.log('read end');
                break;
            } else {
                if (writer.write(data) === false) {
                    console.log('too much pause');

                    if (!noPause) {
                        console.log('pause...');
                        reader.pause();
                    }

                    return false;
                }
            }
        }
        return true;
    }

    //----------------------------
    return def.promise();
}