te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How do pipe (stream of Node.js) and bl (BufferList) work together? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do pipe (stream of Node.js) and bl (BufferList) work together? - Stack Overflow

programmeradmin2浏览0评论

This is actually the exercise No.8 from the Node.js tutorial ([][1])

The goal: Write a program that performs an HTTP GET request to a URL provided to you as the first mand-line argument. Collect all data from the server (not just the first "data" event) and then write two lines to the console (stdout).

The first line you write should just be an integer representing the number of characters received from the server. The second line should contain the plete String of characters sent by the server.

So here's my solution(It passes but looks uglier pared to the official solution).

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();
    });
});

The official solution:

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)
    }))
})

I have difficulties understanding how the official solution works. I have mainly two questions:

  1. The bl constructor expects the 2nd argument to be an instance of bl (according to bl module's documentation, [][2]), but what is data? It came out of nowhere. It should be undefined when it is passed to construct the bl instance.

  2. when is bl.end() called? I can see no where that the bl.end() is called...

Hope someone can shed some light on these questions. (I know I should've read the source code, but you know...)

  [1]: 
  [2]: 

This is actually the exercise No.8 from the Node.js tutorial ([https://github./workshopper/learnyounode][1])

The goal: Write a program that performs an HTTP GET request to a URL provided to you as the first mand-line argument. Collect all data from the server (not just the first "data" event) and then write two lines to the console (stdout).

The first line you write should just be an integer representing the number of characters received from the server. The second line should contain the plete String of characters sent by the server.

So here's my solution(It passes but looks uglier pared to the official solution).

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();
    });
});

The official solution:

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)
    }))
})

I have difficulties understanding how the official solution works. I have mainly two questions:

  1. The bl constructor expects the 2nd argument to be an instance of bl (according to bl module's documentation, [https://github./rvagg/bl#new-bufferlist-callback--buffer--buffer-array-][2]), but what is data? It came out of nowhere. It should be undefined when it is passed to construct the bl instance.

  2. when is bl.end() called? I can see no where that the bl.end() is called...

Hope someone can shed some light on these questions. (I know I should've read the source code, but you know...)

  [1]: https://github./workshopper/learnyounode
  [2]: https://github./rvagg/bl#new-bufferlist-callback--buffer--buffer-array-
Share Improve this question edited Jun 28, 2016 at 14:42 Flip 6,7618 gold badges50 silver badges83 bronze badges asked Jun 18, 2015 at 13:31 some-guy-self-studying-mathsome-guy-self-studying-math 1131 silver badge7 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

This portion of the bl github page more or less answers your question:

Give it a callback in the constructor and use it just like concat-stream:

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 plete Buffer object containing the full data
      console.log(data.toString())   
}))

Note that when you use the callback method like this, the resulting data parameter is a concatenation of all Buffer objects in the list. If you want to avoid the overhead of this concatenation (in cases of extreme performance consciousness), then avoid the callback method and just listen to 'end' instead, like a standard Stream.

You're passing a callback to bl, which is basically a function that it will call when it has a stream of data to do something with. Thus, data is undefined for now... it's just a parameter name that will later be used to pass the text from the GET call for printing.

I believe that bl.end() doesn't have be called because there's no real performance overhead to letting it run, but I could be wrong.

I have read the source code of bl library and node stream API.

BufferList is a custom duplex stream,that is both Readable and Writable.When you run readableStream.pipe(BufferList), by default end() is called on BufferList as the destination when the source stream emits end() which fires when there will be no more data to read.

See the implementation of 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
  }
}

So the callback passed to BufferList, will be called after BufferList received all data from the source stream, call this.slice() will return the result of concatenating all the Buffers in the BufferList where is the data parameter es from.

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

you can have a look on this approach to solve the above exercise, p.s request is a third party module though

发布评论

评论列表(0)

  1. 暂无评论