2017-06-20 12 views
5

tôi đẻ trứng một quá trình con như vậy:dòng chuyển đổi để thêm vào trước chuỗi với từng ngành nghề

const n = cp.spawn('bash'); 

n.stdout.pipe(process.stdout); 
n.stderr.pipe(process.stderr); 

Tôi đang tìm kiếm một biến đổi dòng để tôi có thể thêm vào trước một cái gì đó như '[child process]' đến đầu mỗi dòng từ đứa trẻ, vì vậy tôi biết rằng stdio đến từ đứa trẻ so với quá trình cha mẹ.

Vì vậy, nó sẽ trông như thế:

const getTransformPrepender = function() : Transform { 
    return ... 
} 

n.stdout.pipe(getTransformPrepender('[child]')).pipe(process.stdout); 
n.stderr.pipe(getTransformPrepender('[child]')).pipe(process.stderr); 

không ai biết nếu có một hiện có chuyển đổi gói như thế này hay như thế nào để viết một?

Tôi có điều này:

import * as stream from 'stream'; 


export default function(pre: string){ 

    let saved = ''; 

    return new stream.Transform({ 

    transform(chunk, encoding, cb) { 

     cb(null, String(pre) + String(chunk)); 
    }, 

    flush(cb) { 
     this.push(saved); 
     cb(); 
    } 

    }); 

} 

nhưng tôi sợ nó sẽ không làm việc trong trường hợp cạnh - nơi một đoạn bùng nổ có thể không bao gồm toàn bộ một dòng (đối với dòng rất dài).

Dường như câu trả lời cho điều này là ở đây: https://strongloop.com/strongblog/practical-examples-of-the-new-node-js-streams-api/

nhưng với phụ lục này: https://twitter.com/the1mills/status/886340747275812865

Trả lời

5

Có tổng cộng ba trường hợp mà bạn cần phải xử lý một cách chính xác:

  • Một đoạn đơn đại diện cho toàn bộ một dòng
  • Một đoạn đơn đại diện cho nhiều dòng
  • Một đoạn đơn đại diện chỉ là một phần của dòng

Dưới đây là một mô tả thuật toán để giải quyết tất cả ba tình huống

  1. Nhận một đoạn dữ liệu
  2. Quét đoạn cho dòng mới
  3. Ngay sau khi một dòng mới được tìm thấy, mất tất cả mọi thứ trước khi nó (bao gồm cả newline) và gửi nó ra như một mục dòng duy nhất với bất kỳ sửa đổi bạn cần
  4. Lặp lại cho đến khi toàn bộ đoạn đã được xử lý (không có dữ liệu còn lại) hoặc cho đến khi không newlines bổ sung đã được tìm thấy (một số dữ liệu vẫn còn, lưu nó cho sau này)

Và đây là một thực hiện thực tế với mô tả về lý do tại sao nó là cần thiết, vv.

Xin lưu ý rằng vì lý do hiệu suất, tôi không chuyển đổi bộ đệm thành chuỗi JS cổ điển.

const { Transform } = require('stream') 

const prefix = Buffer.from('[worker]: ') 

const prepender = new Transform({ 
    transform(chunk, encoding, done) { 
    this._rest = this._rest && this._rest.length 
     ? Buffer.concat([this._rest, chunk]) 
     : chunk 

    let index 

    // As long as we keep finding newlines, keep making slices of the buffer and push them to the 
    // readable side of the transform stream 
    while ((index = this._rest.indexOf('\n')) !== -1) { 
     // The `end` parameter is non-inclusive, so increase it to include the newline we found 
     const line = this._rest.slice(0, ++index) 
     // `start` is inclusive, but we are already one char ahead of the newline -> all good 
     this._rest = this._rest.slice(index) 
     // We have a single line here! Prepend the string we want 
     this.push(Buffer.concat([prefix, line])) 
    } 

    return void done() 
    }, 

    // Called before the end of the input so we can handle any remaining 
    // data that we have saved 
    flush(done) { 
    // If we have any remaining data in the cache, send it out 
    if (this._rest && this._rest.length) { 
     return void done(null, Buffer.concat([prefix, this._rest]) 
    } 
    }, 
}) 

process.stdin.pipe(prepender).pipe(process.stdout) 
2

Đây là một công việc đang tiến:

https://github.com/ORESoftware/prepend-transform

nhưng nó được thiết kế để giải quyết vấn đề ở bàn tay như vậy:

import pt from 'prepend-transform'; 
import * as cp from 'child_process'; 

const n = cp.spawn('bash'); 

n.stdout.pipe(pt('[child stdout]')).pipe(process.stdout); 
n.stderr.pipe(pt('[child stderr]')).pipe(process.stderr); 
+0

nhưng chưa hoàn chỉnh, vì nó không thể xử lý các dòng dài đại diện cho nhiều cuộc gọi ('dữ liệu'). –

+0

việc triển khai này chưa hoàn tất và tôi cần trợ giúp để thực hiện chính xác. –

+0

Tôi nghĩ rằng điều này có câu trả lời - https://strongloop.com/strongblog/practical-examples-of-the-new-node-js-streams-api/ –

Các vấn đề liên quan