node5

  • 核心: 对数据进行 CRUD 这几个操作, 很多数据要处理, 这些数据之间有关联, 如何通过关联数据取到其他数据, 对其他数据进行操作
  • require.main 套路
    1
    2
    3
    if (require.main == module) {
    __main()
    }

当 文件的代码被其他文件 require 引入的时候, 其实是把代码从上往下执行了一遍, 用 require.main 的意思是只有执行这段程序所在的文件时, require.main 才是 true, 引入到其他文件的 require.main 为 true, 可以保证这段代码在别的地方不被执行

  • 最外面不要有变量的定义, 所有东西都要用函数包起来
  • 箭头函数与 map 的组合

    1
    const s = Object.keys(mapper).map(k => `${k}: ${mapper[k]}rn`).join('')
  • 做东西先把东西最初的东西显示出来, 改一点测一点, 不能要求一次性写完, 先宏观再微观, 从粗略到细节, 先冗余再重构到抽象.

  • 写程序的规范和模式: 一个路由专门写 view, 写页面, 一个路由专门写逻辑比如写 todo 的时候先 get edit 路由, 跳转到编辑页面, 再在 edit 页面 post update 路由, 写要修改的东西
  • id 传入进来的时候一定要先用 Number 转为同一个类型, 因为js 比较不同类型的时候会自动转, 这样容易出现 bug, 而且 log 字符串的数字和数值的数字打印出来是一样的.
  • 要写what, 不要写how.—明确分工 数据就是 model, 关于数据的操作就应该在 model 里面改, controller 里面只需要拿到 model 给的 api 就可以行了比如要更新数据, 路由函数里面不需要关心如何update, 只需要得到服务器 post 传入的数据, 调用 model 里面的 xx.update(数据) 的 api 就可以了, 具体如何 update 在专门处理数据的 model 里面做, 这一步操作可以一开始就做, 也可以在 route 写好 what 之后确认程序可以运行再抽出去.
  • 数组的替换和删除可以用 splice, 对象的替换直接用 Object[value] = updatedKey
  • 不要依赖JS 的隐试类型转换. return u !== null && true

重定向

如果遇到status code 为 302 的时候, 浏览器会自动在 headers 里面找 Location 的对应的值 (path), 并且会以 get 的形式再发一次请求. 浏览器会自动拼接 protocol, host 等等 和 Location 里面的 path, 形成一个新的页面

301 永久重定向, 302 暂时重定向

重定向的意义: redirect(‘/‘) 函数, 如果不符合规定, 浏览器帮服务器跳转到该去的地方, 比如登录了之后跳转到首页.

form 表单的 content-teype: application/x-www-form-urlencoded

post 表单带 id 数据的方法

1
2
3
4
5
6
7
8
9
10
1.  一致性比较强, 所有数据都在 form 里面
<form action="/todo" method="post">
<input name="id" value="{{id}}" hidden> // 通过 hidden 隐藏id
</form>

2. 写在 path 里面, 通过 query 关键字得到
<form action="/todo/?id={{id}}" method="post"></form>

3. 动态路由, 这种方法要拿 id 必须要通过 parse path 的方法来拿
<form action="/todo/{{id}}" method="post"></form>

CRUD

CRUD (CREATE READ UPDATE DELETE)
delete 的时候需要权限验证

数据与用户关联

在各个数据之间带一个相同的数据值(连通纽带), 比如一个通用的 userId (数据库的外键)
一定要注意 post 传了什么数据给服务器, 共同值(纽带)在各自数据文本之中对应的 key 的名称是什么比如传进来的是id, 值对应的是数据库中 key 是 userId

闭包

方法: 函数套函数, 返回函数
作用:

  1. 把函数作为参数传进来, 如果满足条件, 就执行这个函数, 如果不满足, 就执行其他的操作
  2. 解决全局变量的问题, (函数变量满天飞)
  3. 单例
1
2
3
4
5
6
7
8
9
10
11
const loginRequired = (func) => {
const f = (request) => {
const u = currentUser(request)
if (u === null) {
return redirect('/')
} else {
return func(request)
}
}
return f
}

reduce

多个元素合并成一个元素. Array.reduce(callback(callback的返回值, 数组的每一项), 初始值)

1
2
3
4
5
6
7
8
9
10
11
12
13
1. forEach 方法
headers.forEach((header) => {
const [k, v] = header.split(": ")
this.headers[k] = v
})

2. reduce 方法
headers.reduce((o, item) =>{
const [k, v] = item.split(': ')
o[k] = v
return o
}, this.headers)
// 第一次的 o 是 this.headers, 第二次的 o 是item 第一次计算的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// redux

var compose = (...funcs) => {
return funcs.reduce( (a,b) => (...args) => a(b(...args)))
}

// compose 的每一项参数(参数为函数), ...funcs
// funcs 为 函数组成的数组, 用 ruduce 方法
// 把后一个参数(函数 `b`)的返回值 `b(...args)` 作为 参数 传给 前一个函数`a`

var add = (x ,y ) => x + y
var sum = (...args) => args.reduce( (a, b) => a+b )
var multi = (l) => l * 10
var s = compose(multi, add)
s(1,2)

applyMiddleware( devTools(...args) ) ( persistState(...args) ) ( createStore(...args) )