鸣人火影之路的第一步,就是跟着卡卡西学习基本的忍术,让自己先在忍者的世界里生存下来,so,想要在 node 的世界里游刃有余,必须要掌握异步 I/O、http等核心技能。

ok,第一步先学会读懂需求

// NO1:
// Create a program that prints a list of files in a given directory,filtered by the extension of the files. You will be provided a directory name as the first argument to your program (e.g. '/path/to/dir/') and a file extension to filter by as the second argument. For example, if you get 'txt' as the second argument then you will need to filter the list to only files that end with .txt. Note that the second argument will not come prefixed with a '.'. The list of files should be printed to the console, one file per line. You must use asynchronous I/O. // tips
// The fs.readdir() method takes a pathname as its first argument and a callback as its second. The callback signature is: function callback (err, list) { /* ... */ } // where list is an array of filename strings. //You may also find node's path module helpful, particularly the extname method.
// The answer at the bottom
 
// NO2:
// This problem is the same as the previous but introduces the concept of modules. You will need to create two files to solve this.
// Create a program that prints a list of files in a given directory, filtered by the extension of the files. The first argument is the directory name and the second argument is the extension filter. Print the list of files (one file per line) to the console. You must use asynchronous I/O.
// You must write a module file to do most of the work. The module must export a single function that takes three arguments: the directory name, the filename extension string and a callback function, in that order. The filename extension argument must be the same as what was passed to your program. Don't turn it into a RegExp or prefix with "." or do anything except pass it to your module where you can do what you need to make your filter work.
// The callback function must be called using the idiomatic node(err, data) convention. This convention stipulates that unless there's an error, the first argument passed to the callback will be null, and the second will be your data. In this exercise, the data will be your filtered list of files, as an Array. If you receive an error, e.g. from your call to fs.readdir(), the callback must be called with the error, and only the error, as the first argument.
// You must not print directly to the console from your module file, only from your original program. // These four things are the contract that your module must follow.
// 1. Export a single function that takes exactly the arguments described.
// 2. Call the callback exactly once with an error or some data as described.
// 3. Don't change anything else, like global variables or stdout.
// 4. Handle all the errors that may occur and pass them to the callback. // The benefit of having a contract is that your module can be used by anyone who expects this contract. So your module could be used by anyone else who does learnyounode, or the verifier, and just work. // tips
// The answer at the bottom
// Create a new module by creating a new file that just contains your directory reading and filtering function. To define a single function export, you assign your function to the module.exports object, overwriting what is already there: module.exports = function (args) { /* ... */ } // Or you can use a named function and assign the name. // To use your new module in your original program file, use the require() call in the same way that you require('fs') to load the fs module. The only difference is that for local modules must be prefixed with './'. So,
// if your file is named mymodule.js then: var mymodule = require('./mymodule.js')

怎么样?是不是发现自己有时连需求都看不懂!没关系,下面就是中文了,不过最新的、高质量的新技术都是通过英语来传播的,所以最好还是坚持学英语,读英语技术书籍、博客!

// NO3
// 这次的问题需要使用到 http.get() 方法。然而,这一次,将有三个 URL 作为前三个命令行参数提供给你。
// 你需要收集每一个 URL 所返回的完整内容,然后将它们在终端(标准输出stdout)打印出来。这次你不需要打印出这些内容的长度,仅仅是内容本身即可(字符串形式);每个 URL 对应的内容为一行。重点是你必须按照这些URL在参数列表中的顺序将相应的内容排列打印出来才算完成。 // 提示
// 不要期待这三台服务器能好好的一起玩耍!他们可能不会把完整的响应的结果按照你希望的顺序返回给你,所以你不能天真地只是在收到响应后直接打印出来,因为这样做的话,他们的顺序可能会乱掉。
// 你需要去跟踪到底有多少 URL 完整地返回了他们的内容,然后用一个队列存储起来。一旦你拥有了所有的结果,你才可以把它们打印到终端。
// NO4:编写一个 TCP 时间服务器  

// 你的服务器应当监听一个端口,以获取一些 TCP 连接,这个端口会经由第一个命令行参数传递给你的程序。针对每一个 TCP 连接,你都必须写入当前的日期和24小时制的时间,如下格式:  

//     "YYYY-MM-DD hh:mm"  

//  然后紧接着是一个换行符。  

//  月份、日、小时和分钟必须用零填充成为固定的两位数:  

//     "2013-07-06 17:42"  

// 提示
// 这次练习中,我们将会创建一个 TCP 服务器。这里将不会涉及到任何 HTTP 的事情,因此我们只需使用 net 这个 Node 核心模块就可以了。它包含了所有的基础网络功能。 // net 模块拥有一个名叫 net.createServer() 的方法,它会接收一个回调函数。和 Node 中其他的回调函数不同,createServer() 所用的回调函数将会被调用多次。你的服务器每收到一个 TCP 连接,都会调用一次这个回调函数。这个回调函数有如下特征: function callback (socket) { /* ... */ } // net.createServer() 也会返回一个 TCP 服务器的实例,你必须调用 server.listen(portNumber) 来让你的服务器开始监听一个特定的端口。 // 一个典型的 Node TCP 服务器将会如下所示: var net = require('net')
var server = net.createServer(function (socket) {
// socket 处理逻辑
})
server.listen(8000) //socket 对象包含了很多关于各个连接的信息(meta-data),但是它也同时是一个 Node 双工流(duplex Stream),所以,它即可以读,也可以写。对这个练习来说,我们只需要对 socket 写数据和关闭它就可以了。 // 使用 socket.write(data) 可以写数据到 socket 中,用 socket.end() 可以关闭一个 socket。另外, .end() 方法也可以接收一个数据对象作为参数,因此,你可简单地使用 socket.end(data) 来完成写数据和关闭两个操作。
// NO5
// 编写一个 HTTP 文件 服务器,它用于将每次所请求的文件返回给客户端。 你的服务器需要监听所提供给你的第一个命令行参数所制定的端口。 同时,第二个会提供给你的程序的参数则是所需要响应的文本文件的位置。在这一题中,你必须使用 fs.createReadStream() 方法以 stream 的形式作出请求相应。
// 提示
//一个典型的 Node HTTP 服务器将会是这个样子: var http = require('http')
var server = http.createServer(function (req, res) {
// 处理请求的逻辑...
})
server.listen(8000) // fs 这个核心模块也含有一些用来处理文件的流式(stream) API。你可以使用 fs.createReadStream() 方法来为命令行参数指定的文件创建一个 stream。这个方法会返回一个 stream 对象,该对象可以使用类似 src.pipe(dst) 的语法把数据从 src流传输(pipe) 到 dst流中。通过这种形式,你可以轻松地把一个文件系统的 stream 和一个 HTTP 响应的 stream 连接起来。
// NO6
// 编写一个 HTTP 服务器,它只接受 POST 形式的请求,并且将 POST 请求主体(body)所带的字符转换成大写形式,然后返回给客户端。 // 提示
// through2-map 允许你创建一个 transform stream,它仅需要一个函数就能完成「接收一个数据块,处理完后返回这个数据块」 的功能 ,它的工作模式类似于 Array#map(),但是是针对 stream 的: var map = require('through2-map')
inStream.pipe(map(function (chunk) {
return chunk.toString().split('').reverse().join('')
})).pipe(outStream)
// NO7 HTTP JSON API 服务器 

// 编写一个 HTTP 服务器,每当接收到一个路径为 '/api/parsetime' 的 GET 请求的时候,响应一些 JSON 数据。我们期望请求会包含一个查询参数(query string),key 是 "iso",值是 ISO 格式的时间。  

  /api/parsetime?iso=2013-08-10T12:10:15.474Z  

//  所响应的 JSON 应该只包含三个属性:'hour','minute' 和 'second'。例如:  

     {
"hour": 14,
"minute": 23,
"second": 15
} // 然后增再加一个接口,路径为 '/api/unixtime',它可以接收相同的查询参数(query string),但是它的返回会包含一个属性:'unixtime',相应值是一个 UNIX 时间戳。例如: { "unixtime": 1376136615474 } //提示
// 你可以使用 Node 的核心模块 'url' 来处理 URL 和 查询参数(query string)。 url.parse(request.url, true) 方法会处理 request.url,它返回的对象中包含了一些很有帮助的属性,方便方便你处理 querystring。
// 你也应当争做 Web 世界的好公民,正确地为响应设置 Content-Type 属性: res.writeHead(200, { 'Content-Type': 'application/json' })

Pseudo code

// NO1
   var fs = require('fs')
var path = require('path') var folder = process.argv[2]
var ext = '.' + process.argv[3] fs.readdir(folder, function (err, files) {
if (err) return console.error(err)
files.forEach(function (file) {
if (path.extname(file) === ext) {
console.log(file)
}
})
})
// NO2
// ./solution/solution.js_ : var filterFn = require('./solution_filter.js')
var dir = process.argv[2]
var filterStr = process.argv[3] filterFn(dir, filterStr, function (err, list) {
if (err) {
return console.error('There was an error:', err)
} list.forEach(function (file) {
console.log(file)
})
}) // ./solution/solution_filter.js_ : var fs = require('fs')
var path = require('path') module.exports = function (dir, filterStr, callback) {
fs.readdir(dir, function (err, list) {
if (err) {
return callback(err)
} list = list.filter(function (file) {
return path.extname(file) === '.' + filterStr
}) callback(null, list)
})
}
// NO3
var http = require('http');
var i = 2,
aCon = []; function filterFn(aUrl) { if (i < 5) {
http.get(aUrl[i], function (res) {
res.setEncoding('utf8');
let rowData = ''; res.on('data', function (data) {
rowData += data;
}).on('end', ()=>{
i++;
aCon.push(rowData);
filterFn(aUrl);
}).on('error', (e) => {
console.log($(e.message));
});
});
} else {
aCon.forEach(function (val) {
console.log(val);
});
}
} filterFn(process.argv);
// NO4
var net = require('net') function zeroFill (i) {
return (i < 10 ? '0' : '') + i
} function now () {
var d = new Date()
return d.getFullYear() + '-' +
zeroFill(d.getMonth() + 1) + '-' +
zeroFill(d.getDate()) + ' ' +
zeroFill(d.getHours()) + ':' +
zeroFill(d.getMinutes())
} var server = net.createServer(function (socket) {
socket.end(now() + '\n')
}) server.listen(Number(process.argv[2]))
    // NO5
var http = require('http')
var fs = require('fs') var server = http.createServer(function (req, res) {
res.writeHead(200, { 'content-type': 'text/plain' }) fs.createReadStream(process.argv[3]).pipe(res)
}) server.listen(Number(process.argv[2]))
// NO6
const server = http.createServer((req, res) => {
if (req.method != 'POST') {
return res.end('send a POST\n');
} req.pipe(map(function (chunk) {
return chunk.toString().toUpperCase();
})).pipe(res);
}); server.listen(Number(process.argv[2]));
    // NO7
var http = require('http')
var url = require('url') function parsetime (time) {
return {
hour: time.getHours(),
minute: time.getMinutes(),
second: time.getSeconds()
}
} function unixtime (time) {
return { unixtime: time.getTime() }
} var server = http.createServer(function (req, res) {
var parsedUrl = url.parse(req.url, true)
var time = new Date(parsedUrl.query.iso)
var result if (/^\/api\/parsetime/.test(req.url)) {
result = parsetime(time)
} else if (/^\/api\/unixtime/.test(req.url)) {
result = unixtime(time)
} if (result) {
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify(result))
} else {
res.writeHead(404)
res.end()
}
})
server.listen(Number(process.argv[2]))

PS: nodeSchool

Ninja 之路:试炼!求生演习——异步 I/O、http的更多相关文章

  1. 嵌入式Linux驱动学习之路(十三)按键驱动-异步通知

    之前的按键方式: 查询: 极度占用CPU资源 中断: 在读的时候产生休眠,在没有信号的时候永远不会返回. poll机制: 在中断的基础上加上超时时间. 异步通知就是通过信号来传送. 首先在应用程序中有 ...

  2. IOS学习之路七(使用 Operation 异步运行任务)

    在 application delegate 头文件(.h)中声明一个 operation 队列和两个 invocation operations: #import <UIKit/UIKit.h ...

  3. 【CLR VIA C#】读书笔记

    工作几年了才看,记录下笔记备忘. 章节 笔记 1.CLR的执行模型 公共语言运行时(Common Language Runtime,CLR) 源代码-->编译器检查语法和分析源代码-->托 ...

  4. vue ssr 项目改造经历

    vue ssr 项目改造经历 由于工作项目需求,需要将原有的项目改造,vue ssr 没有用到nuxt,因为vue ssr更利于seo,没办法,一个小白的改造经历, 首先说明一下,小白可以借鉴,高手也 ...

  5. Linux日志管理系统rsyslog

    一.日志的概念 什么是日志?日志就是历史事件.历史事件包括时间.地点.人物.时间.这个是生活中所说的日志很好理解.在Linux中也有类似的服务,它主要作用就是记录Linux系统的历史事件,包括什么时间 ...

  6. Python之路,Day10 - 异步IO\数据库\队列\缓存

    Python之路,Day9 - 异步IO\数据库\队列\缓存   本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...

  7. Node.js之路【第三篇】NodeJS异步实现

    NodeJS异步实现 Node.js异步编程的直接体现就是回调,它依托于回调来实现,但不能说使用了回调他就是异步了 回调函数在完成任务后就会被调用,Node使用了大量的回调函数,Node所有的API都 ...

  8. Python之路第一课Day10--随堂笔记(异步IO\数据库\队列\缓存)

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

  9. EF架构~EF异步改造之路~仓储接口的改造

    回到目录 返回异步与并行目录 C#5.0带来了并行编程 {C#1.0托管代码→C#2.0泛型→C#3.0LINQ→C#4.0动态语言→C#5.0异步编程} 随着C#5.0在.net4.5出来之后,它们 ...

随机推荐

  1. flex中日期的格式化

    今天我做的项目中需要把时间给拆分了,形式为:yyyy-MM-DD HH mm, 下面是我的代码实现: <?xml version="1.0" encoding="u ...

  2. 【前端调试手机页面】分享一款便捷的调试工具--spy-debugger

    spy-debugger  :  微信调试,各种WebView样式调试.手机浏览器的页面真机调试.便捷的远程调试手机页面.抓包工具,支持:HTTP/HTTPS,无需USB连接设备. github地址: ...

  3. Java排序算法之直接选择排序

    Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...

  4. 【干货分享】sketch 前端开发常用技巧总结

    sketch横空出世,移动端的应用越来越多的采用sketch来做,前端开发也需要掌握更多sketch技巧. (1) sketch导出图片时,如何快速选择多个图层? 1. 在画布上任一点单击并拖拽出一个 ...

  5. AtCoder Beginner Contest 055题解

    A.当a=1就把a改成14,b=1就把b改成14,然后比较a,b大小即可. #include <iostream> #include <algorithm> #include ...

  6. JavaWeb之cookie

    什么叫做会话 ? 用户从打开一个浏览器开始,浏览器网站,到关闭浏览器的整个过程叫做一次会话! 每个用户与服务器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据. 例如:用户点击超链接 ...

  7. fixed应用

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. WebGL 创建和初始化着色器过程

    1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...

  9. JavaScript 格式化时间

    //格式化 yyyy-MM-dd hh:mm:ss function renderTime(date) { if (date == '' || date == null) { return ''; } ...

  10. huffman压缩解压文件【代码】

    距离上次写完哈夫曼编码已经过去一周了,这一周都在写huffman压缩解压,哎,在很多小错误上浪费了很多时间调bug.其实这个程序的最关键部分不是我自己想的,而是借鉴了某位园友的代码,但是,无论如何,自 ...