教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载本篇技术指南围绕 learnyounode 自导式 Node.js 工作坊中的HTTP COLLECThttp_collect练习展开讲解如何对命令行传入的 URL 发起 HTTP GET 请求、跨越多个data事件完整收集响应数据并按要求向 stdout 输出两行内容字符总数与完整响应字符串。读完本文你将掌握原生事件监听与第三方流收集bl、concat-stream两种方案理解 learnyounode 内置测试服务器与verify校验机制的工作原理并能在本地独立复现、运行与验证该练习。练习目标与验收标准本练习的完整题面位于 exercises/http_collect/problem.tr.md土耳其语版本文件名为http-topla.js其英文原版见 exercises/http_collect/problem.md。作为 learnyounode 工作坊的第 8 个练习完整练习清单见 learnyounode.js其中依次包含 HELLO WORLD、BABY STEPS、MY FIRST I/O!、MY FIRST ASYNC I/O!、FILTERED LS、MAKE IT MODULAR、HTTP CLIENT、HTTP COLLECT、JUGGLING ASYNC、TIME SERVER、HTTP FILE SERVER、HTTP UPPERCASERER、HTTP JSON API SERVER它是 HTTP CLIENT仅打印响应数据与 JUGGLING ASYNC并发收集多个 URL之间的关键过渡关卡。程序要求创建一个名为http-topla.js英文版为http-collect.js的文件程序以命令行第一个参数process.argv[2]作为 URL向其发起 HTTP GET 请求收集服务器返回的全部数据——注意不是仅仅第一个data事件的数据向控制台stdout输出两行第一行服务器响应的字符数整数第二行服务器返回的完整字符串内容。验收命令为$ learnyounode verify http-topla.js值得强调的是练习中字符数指的是对完整响应调用data.toString()之后的字符串长度data.length这一细节直接决定了bl回调中必须先完成 Buffer 到字符串的转换。方案一使用原生事件收集跨data事件的数据练习提示给出的第一种方案不依赖任何第三方库监听多个data事件并逐块拼接再用end事件判定流结束并输出结果。基于 Buffer 数组拼接的参考实现测试用例 test/http_collect/valid_03.js 完整展示了这一思路const http require(http) const bufferArray [] http.get(process.argv[2], response { response.on(data, chunk { bufferArray.push(chunk) }).on(end, () { const data Buffer.concat(bufferArray).toString() console.log(data.length) console.log(data) }) })关键点response.on(data, ...)可能被触发多次每次回调收到的chunk是Buffer类型默认编码下将每个 chunk 压入数组待end事件触发后用Buffer.concat()合并为单一 Buffer最后通过.toString()转为字符串先输出data.length字符数再输出data本身end事件代表响应体传输完毕是流已结束的权威信号。手动拼接字符串的简易版本如果确认响应为文本也可以在data回调中直接做字符串累加注意不要漏掉编码转换http.get(process.argv[2], function (response) { let rawData response.setEncoding(utf8) response.on(data, chunk { rawData chunk }) response.on(end, () { console.log(rawData.length) console.log(rawData) }) })其中response.setEncoding(utf8)让chunk直接成为字符串内部由 StringDecoder 完成解码该用法与 exercises/http_client/solution/solution.js 中response.setEncoding(utf8)的处理方式一致。方案一适合理解流式数据的基本语义但手动管理拼接逻辑在处理大量分块时容易出错这正是方案二存在的意义。方案二使用bl或concat-stream一次性收集整个流练习提示给出的第二种方案是引入第三方包来封装收集整个流的复杂性。官方推荐了两个 API 高度相似的包blBuffer List和concat-stream。两者均可作为可写流接收被pipe()进来的数据并在流结束后以回调形式返回完整数据。安装第三方包使用 npm 安装例如bl$ npm install bl该命令会把最新版本下载到当前目录下的node_modules子目录中。package.json中声明的依赖确认了 learnyounode 自身使用的版本范围bl: ^4.0.0与concat-stream: ^2.0.0。安装后程序主文件可以用require直接加载包无需./前缀const bl require(bl)Node 的模块解析顺序是先查找核心模块再到node_modules目录中查找。核心用法将响应流 pipe 进收集器练习文档给出了两种等价写法response.pipe(bl(function (err, data) { /* ... */ })) // 或 response.pipe(concatStream(function (data) { /* ... */ }))两者的细微差别在于回调签名bl回调为(err, data)concat-stream回调仅接收data。共同要点是回调中的data是 Buffer 对象必须调用data.toString()转换为字符串后才能计算字符数并输出。仓库内标准答案 exercises/http_collect/solution/solution.js 完整实现了这一方案use strict const http require(http) const 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) })) })对照测试用例 test/http_collect/valid_01.js 与 test/http_collect/valid_02.js两者与官方答案逻辑完全一致可以作为本练习的权威验收范本。离线环境安装若机器没有互联网连接练习文档给出了一条离线安装路径手动创建node_modules目录并从 learnyounode 安装目录内复制对应包node_modules/bl node_modules/concat-stream对应题面中的{rootdir:/node_modules/bl}与{rootdir:/node_modules/concat-stream}占位符。此外安装 learnyounode 时已随包附带这两个模块的离线 HTML 文档可直接在浏览器中打开阅读docs/bl.html 与 docs/concat-stream.html。深入理解blBufferList的实现原理bl本质上是一个 Node.jsBuffer 列表收集器、读取器与流式工具它是 Buffer 对象的存储容器对外暴露 Buffer 的主流可读 API同时自身是一个Duplex双工流——既能从上游流收集 Buffer也能作为可读流把数据输出给下游流。从 docs/bl.html 可以提炼出与本练习直接相关的三个设计要点零拷贝设计原始 Buffer 会被原样保留仅在必要时才发生拷贝。若读取范围落在单个内部 Buffer 上slice()返回的是与原 Buffer 共享同一内存的切片只有当范围跨越多个 Buffer 时才执行拼接并透明地返回结果。构造器回调在构造时传入回调函数如bl(fn)或new BufferList(fn)当bl.end()被调用即来自 pipe 的流结束时回调会收到错误参数与指向 bl 实例的引用。这正是本练习response.pipe(bl(callback))的底层机制。文档还特别指出new并非强制要求未实例化时会自动完成创建。关键 APIbl.length字节长度、bl.append(buffer)追加 Buffer、bl.slice([start[, end]])按范围取切片、bl.consume(bytes)从列表头部消费字节、bl.toString([encoding[, start[, end]]])字符串化以及全套readUInt16BE/readInt32LE等二进制读取方法。使用回调方式收集数据时data参数是列表中所有 Buffer 的拼接结果官方文档也提示在极端追求性能的场景下可以避免回调方式改用监听标准流的end事件来规避拼接开销——这与方案一的思路殊途同归。测试服务器与验证机制源码级分析了解判题原理有助于写出一次通过的代码。练习的判题逻辑位于 exercises/http_collect/exercise.js其关键实现如下构造慢速分块测试服务器exercise.addSetup中创建一个 HTTP 服务器使用boganipsum生成两段随机文本并按单词切分每个单词通过res.write(words[i] )输出且每个单词间隔setTimeout(..., 2)毫秒——这是刻意设计的慢速分块输出用于考验程序是否真正等待全部数据。自动注入 URL 参数服务器监听随机端口this.server.listen(0)随后把http://localhost:port作为命令行参数分别注入提交程序与标准答案this.submissionArgs [url]、this.solutionArgs [url]。长输出比较模式exercise.longCompareOutput true表明判题器会对长文本输出进行对齐比较因此两行输出字符数 完整内容的顺序和完整性都不可省略。清理机制addCleanup在 run/verify 结束后关闭服务器。verify命令会同时运行你的程序与官方答案exercises/http_collect/solution/solution.js对比两者输出。由于服务器数据被拆分成大量 2ms 间隔的小块若程序只监听第一次data事件就输出字符数将明显偏小必然无法通过验证。常见错误与调试建议忘记toString()转换bl回调中的data是 Buffer直接输出data.length得到的是字节数而非字符数且第二行会打印出 Buffer 的二进制内容。对照测试用例 test/http_collect/invalid_01.js 可见这正是典型反例它在bl回调中未转换就直接console.log(data.length)与console.log(data)。只处理第一个data事件面对 2ms 间隔的慢速分块流只取首个 chunk 会丢失绝大部分数据字符数统计必然错误。忽略end事件方案一中若在最后一个data之后立即输出可能仍处于流传输中途。忽略错误处理http.get与响应流都可能触发error事件如服务器异常官方答案在bl回调中通过if (err) return console.error(err)做了防御建议保留。进阶扩展向 JUGGLING ASYNC 过渡HTTP COLLECT 的bl收集模式在下一个练习 JUGGLING ASYNC 中被直接复用并升级并发对 3 个 URL 发起 GET 请求、分别收集完整响应且必须按命令行参数顺序输出。参考实现 exercises/juggling_async/solution/solution.js 展示了关键模式response.pipe(bl(function (err, data) { if (err) return console.error(err) results[index] data.toString() count if (count 3) printResults() }))它用results数组按索引保存每次收集的结果并用计数器count等待全部 3 个请求完成后才统一打印——这正是本练习收集完整数据能力在并发场景下的延伸。理解 http_collect 的bl用法是掌握 juggling_async 顺序输出技巧的前提。小结HTTP COLLECT 练习的核心训练点是流式数据的完整收集方案一通过dataend事件与Buffer.concat()手动拼接帮助理解流生命周期方案二借助bl/concat-stream以pipe 回调的方式优雅收口并需牢记 Buffer 到字符串的toString()转换。配合 learnyounode 内置的慢速分块测试服务器exercises/http_collect/exercise.js与verify http-topla.js校验命令你可以在本地完整复现并验证两种方案的差异为后续 JUGGLING ASYNC 的并发收集打下坚实基础。赞分享教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载相关推荐nextjs-use-php 对比 react-use-c 与 react-use-rust在 React 中嵌入多语言的 3 种思路nextjs use php 对比 react use c 与 react use rust在 React 中嵌入多语言的 3 种思路 nextjs use教程CLIlearnyounode 第 7 关 HTTP CLIENT用 Node.js http.get() 发起 GET 请求并消费响应流learnyounode 第 7 关 HTTP CLIENT用 Node.js http.get 发起 GET 请求并消费响应流 本文是 learnyouno教程CLIlearnyounode HTTP CLIENT 练习详解用 Node.js 的 http.get() 编写第一个 HTTP GET 客户端learnyounode HTTP CLIENT 练习详解用 Node.js 的 http.get 编写第一个 HTTP GET 客户端 本指南围绕 lear教程CLI上一篇告别逐条手动记账三步跑通 local-llms-analyse-finance 本地 AI 财务分类下一篇Apache Pulsar 术语表从 Message 到 Ledger 的核心概念与架构解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考