文章目录
记得高二老师的一句话:基础不牢,地动山摇,基础不稳,做题不准
二刷vue全家桶文档
vue的API设计堪称优美, 特别是2.0向react看齐改了非常多的API名称,因此二刷文档其实挺舒服的。
这一块记录之前不知道或者未重视的地方
v-bind又支持filter了
v2.1.0新特性,v1.0本来v-bind支持filter,但是Evan在v2里给去除了,仅在文字指令中才能使用
当时beta版本时就有个issue,一大堆人哀嚎让filter还回来,Evan终于还是在v2.1松口了
nextTick返回Promise
v2.1.0新特性,感觉又是一个语法糖,返回Promise要求没有回调传给nextTick。
那么,下一步是不是让那三个路由钩子next参数也返回Promise?
组件的key属性
vue2的数据响应比我想象中要坑不少。有如下一个场景:
同一个echarts图表子组件被v-for指令渲染了两次,当子组件初始化完毕后,修改传给第二个子组件的数据,然而它并没有变化。
出现这个问题后,排查了很久确定不是echarts的锅,可能是组件被vue2缓存了,因此将这个子组件用不同名称导入了两次,临时解决了这个问题。
仔细查询API文档后,发现一个key属性,当它变化时组件必然变化,并触发组件生命周期,因此能够强制禁止掉组件的缓存。
css module
写行内样式还是得css module来,react的css module我用的还是蛮爽的,vue-loader v9.8.0终于支持这个了
watch的immediate属性
vm.$watch('$route', callback, {
immediate: true
})
不加immediate参数的话,刚进入此组件时$route并不会被触发,还要额外在beforeRouteEnter中做额外的工作。
知道immediate就方便多了
created组件生命周期
最好在这个组件生命周期钩子中触发XHR获取数据,它比beforeMount早了很多
v-clock指令
{{value}}
这是一个典型的模版写法,在value未被计算前,两组大括号会被用户看到。v-clock配合样式,可以隐藏这种问题
v-pre指令
加了这个指令的dom模版,不会被vue编译,可以做一点微小的加速
v-once指令
模版只会被渲染一次,同样用来做加速
$isServer
Vue.prototype.$isServer, 文档里只提了vm.$isServer。
这会在SSR时需要用到,判断是否在服务端环境,因为SSR时并没有一个vm实例给你拿$isServer,但是不能忘记实例的好多方法是在原型链上的,即使文档不告诉我们,我们也应该能猜到Vue.prototype.$isServer也能拿到这个值
v-else-if指令
又一个语法糖
条件keep-alive
这是个好东西,比语法糖好多了
beforeEach的强大
作为vue-router的三个路由钩子最顶级的一种,beforeEach会在任何情况下被触发,特别是仅当params/query变化时,而beforeEnter和beforeRouteEnter在这种情况下不会被触发
chrome v55发布
async/await终于不用flag就能用了,然而node v7.2.0的v8版本还是v54,估计得等node v8.0才能用上。 我对async/await非常喜欢,虽然是假协程。
process.versions.v8 // 5.4.500.36
博主是今年4月份才开始写node的,不过在写这之前就刷过五本node的书,并且是在确认有办法解决回调的情况下(使用babel转async/await),才正式开始写第一行代码
kafka-node
kafka-node是搜狐出的kafka客户端,蛮不错的,支持0.8.1以上,因为0.9的api与低级版本稍微有冲突,没想到kafka-node能够直接支持。
这里记录一下消费者订阅时outOfRange的报错如何解决,官方文档写的比较分散。
consumer.on('error', (err) => {
log.error(err);
})
consumer.on('message', function (message) {
log.debug(message);
log.debug('==========>')
});
let offset = new kafka.Offset(client);
consumer.on('offsetOutOfRange', function (topic) {
topic.maxNum = 2;
topic.time = -2;
offset.fetch([topic], function (err, offsets) {
let min = Math.min.apply(null, offsets[topic.topic][topic.partition]);
log.debug('offsets:', offsets, 'min:', min)
consumer.setOffset(topic.topic, topic.partition, min);
});
});
问题在于,topic的offset初始时大概率并不为0, 这时又没法取得当前的offset,因此只能在offsetOutOfRange这个错误里去手动获取并指定offset。
webpack打包时的发现
- tree-shaking与webpack的分vendor加载有冲突
- 分析客户端打包文件
- 用了es6-promise的话,不要忘记在webpack中用noParser将es6-promise过滤掉,否则webpack会多打2k代码进来
- vue的transition模块博主完全没用到,代码量却占比不少,迟早要自己打包干掉它。
- 发现EventEmitter的源码被打进来了,但是我的业务代码并没有加载它,还得找个时间分析一下哪个依赖这么蛋疼
分析EventEmitter在哪里被打入
全局安装webpack-bundle-size-analyzer
webpack --config ./buildack.client.config.js --json | webpack-bundle-size-analyzer
发现不是EventEmitter而是component-emitter
,这个包被superagent引用,好吧我忍了
SSR 异步组件
我等你好久了,你却三年来一回
一道题
当初leader面我时,有一道题我回答得貌似挺有道理的,然而三个月后我把题目都快忘了。再次记录一波
let arr = [1,2,3,4,5];
for (let n of arr) {
console.log(n);
arr = [];
}
问上面的代码是输出1, 还是1,2,3,4,5.
猜都能猜到是1,2,3,4,5,但是解释起来就难了。我当时是回答,for of循环里,n拿到的实际上是迭代器,类似arr.next()这样的引用,因此即使修改arr也能拿到值。感觉也可以自圆其说
let arr = [1,2,3,4,5];
for (var n in arr) {
console.log(n);
arr = [];
}
如上代码输出0,1,2,3,4, 没有问题,但是这里无法用迭代器来解释了。
再用如下代码实验
let arr = [1,2,3,4,5];
for (let n in arr) {
console.log(n);
delete arr[1]
arr = [];
}
输出0,2,3,4 删掉数组第二位后,发现for in循环少了一次,因此可以认为for in/of 循环中, 每次迭代的都是一个原始引用,直接修改变量也无法gc掉那个原始引用,因为它在for in/of中有一个引用计数。
这样就可以同时解释上面两种情况了。
按上面的说法,那么如下代码应当输出0,1,2,3,4
let arr = [1,2,3,4,5];
for (let n in arr) {
console.log(n);
arr = [];
arr.push(n)
}
运行了一下,没有问题
.gitignore
需要跟踪忽略文件夹中某个文件的话, 文件夹结尾得有*号
dist/ #wrong
dist/* #right
!dist/server-bundle.js
mongo查询
有张表内有两亿条数据,在查询时发现几个怪异现象,记录一波,等空闲时间找一下问题所在。
- $gt查询非常慢,查一条最近一分钟的数据都要八分钟,而$lt查询快得一笔,马上就出来了
- 直觉是$gt是按natural排序查的,因此从旧数据一直查过来,$lt是按$natural:-1来查的,因此非常快
- 但是$gt查询时sort一下,仍然没有任何效果
- 直觉是$gt是按natural排序查的,因此从旧数据一直查过来,$lt是按$natural:-1来查的,因此非常快
- 删除时比较慢,删了接近两个小时,但是count表数据总数时非常快,毫秒级别
- 感觉这就算是空间换时间的意思?
- 这张表除了id外没有索引,在有对应字段索引时$gt查询效果会如何呢
- 抽个时间造个100万条试试,毕竟连alpha的机器人每天都要塞千万级的数据进mongo呢。。。
- 查询时,对一个属性正则匹配,对另一个属性使用$gt,这两者的排列顺序是否会影响查询的效率?