2015-06-18 24 views
9

Đây thực sự là số 8 tập thể dục từ các hướng dẫn Node.js ([https://github.com/workshopper/learnyounode][1])Đường ống (luồng Node.js) và bl (BufferList) hoạt động cùng nhau như thế nào?

Mục tiêu: Viết chương trình thực hiện một yêu cầu HTTP GET đến một URL được cung cấp cho bạn như Command- đầu tiên đối số dòng. Thu thập tất cả dữ liệu từ máy chủ (không chỉ là sự kiện "dữ liệu" đầu tiên) và sau đó viết hai dòng vào bảng điều khiển (stdout).

Dòng đầu tiên bạn viết chỉ là số nguyên thể hiện số lượng ký tự nhận được từ máy chủ. Dòng thứ hai phải chứa chuỗi ký tự hoàn chỉnh được gửi bởi máy chủ.

Vì vậy, đây là giải pháp của tôi (Nó vượt qua nhưng trông xấu hơn so với giải pháp chính thức).

var http = require('http'), 
bl = require('bl'); 

var myBL = new bl(function(err, myBL){ 
    console.log(myBL.length); 
    console.log(myBL.toString()); 
}); 

var url = process.argv[2]; 
http.get(url, function(res){ 
    res.pipe(myBL); 
    res.on('end', function(){ 
     myBL.end(); 
    }); 
}); 

Các giải pháp chính thức:

var http = require('http') 
var bl = require('bl') 

http.get(process.argv[2], function (response) { 
    response.pipe(bl(function (err, data) { 
     if (err) 
      return console.error(err) 
     data = data.toString() 
     console.log(data.length) 
     console.log(data) 
    })) 
}) 

tôi gặp khó khăn tìm hiểu cách các giải pháp chính thức hoạt động. Tôi có chủ yếu là hai câu hỏi:

  1. Các constructor bl hy vọng đối số thứ 2 là một thể hiện của bl (theo tài liệu hướng dẫn bl mô-đun của, [https://github.com/rvagg/bl#new-bufferlist-callback--buffer--buffer-array-][2]), nhưng dữ liệu là gì? Nó ra khỏi hư không. Nó sẽ không được xác định khi nó được truyền để xây dựng thể hiện bl.

  2. khi nào là bl.end() được gọi? Tôi có thể thấy không có nơi nào bl.end() được gọi là ...

Hy vọng ai đó có thể làm sáng tỏ những câu hỏi này. (Tôi biết tôi nên đã đọc mã nguồn, nhưng bạn biết ...)

[1]: https://github.com/workshopper/learnyounode 
    [2]: https://github.com/rvagg/bl#new-bufferlist-callback--buffer--buffer-array- 

Trả lời

6

phần này của trang bl github nhiều hay ít trả lời câu hỏi của bạn:

Cho nó một callback trong các nhà xây dựng và sử dụng nó giống như concat dòng:

const bl = require('bl') 
, fs = require('fs') 

fs.createReadStream('README.md') 
    .pipe(bl(function (err, data) { // note 'new' isn't strictly required 
     // `data` is a complete Buffer object containing the full data 
     console.log(data.toString()) 
})) 

Lưu ý rằng khi bạn sử dụng phương pháp gọi lại như thế này, kết quả tham số dữ liệu là một nối của tất cả các đối tượng Buffer trong ngày e danh sách. Nếu bạn muốn tránh chi phí của việc ghép nối này (trong trường hợp trường hợp nhận thức cực kỳ hiệu suất), thì hãy tránh phương thức gọi lại và chỉ cần nghe 'kết thúc' thay thế, như một luồng chuẩn.

Bạn đang chuyển một callback tới bl, về cơ bản là một chức năng mà nó sẽ gọi khi có luồng dữ liệu để thực hiện điều gì đó. Do đó, dữ liệu không được xác định ngay bây giờ ... nó chỉ là một tên tham số mà sau này sẽ được sử dụng để truyền văn bản từ lệnh gọi GET để in.

Tôi tin rằng bl.end() không được gọi vì không có chi phí thực sự thực sự để cho phép nó chạy, nhưng tôi có thể sai.

+0

Về 'end', xem tại đây - https://github.com/rvagg/bl # ctor – levi

+0

Cảm ơn cả hai! Thật vậy, xấu của tôi, tôi nên đọc tài liệu cẩn thận hơn. 1) tham số dữ liệu được sử dụng như một tham số đầu ra và bl không yêu cầu nó là một thể hiện của bl. (Tôi đã bị lừa bởi mô tả ở đây https://github.com/rvagg/bl#new-bufferlist-callback--buffer--buffer-array- – slowreader239

+0

2) Đối với cuộc gọi kết thúc(), thực sự nó được cho là được gọi là bởi stream.pipe() https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options – slowreader239

3

Tôi đã đọc mã nguồn của thư viện blnode stream API.

BufferList được một dòng tùy chỉnh duplex, có nghĩa là cả hai có thể đọc và Writable.When bạn chạy readableStream.pipe(BufferList), theo mặc định end() được kêu gọi BufferList là điểm đến khi con suối nguồn phát ra end() mà cháy khi sẽ không có nhiều dữ liệu để đọc .

Xem implementation của BufferList.prorotype.end:

BufferList.prototype.end = function (chunk) { 
    DuplexStream.prototype.end.call(this, chunk) 

    if (this._callback) { 
    this._callback(null, this.slice()) 
    this._callback = null 
    } 
} 

Vì vậy, khi gọi lại truyền cho BufferList, sẽ được gọi sau khi BufferList nhận tất cả các dữ liệu từ các suối nguồn, gọi this.slice() sẽ trả lại kết quả của việc liên tiếp các Buffers trong BufferList thông số data xuất phát từ đâu.

0
var request=require('request') 
request(process.argv[2],function(err,response,body){ 
console.log(body.length); 
console.log(body); 
}) 

bạn có thể có một cái nhìn về phương pháp này để giải quyết các bài tập trên, ps yêu cầu là một mô-đun của bên thứ ba mặc dù

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