2016-12-04 22:19:00

十二月随手记

记得高二老师的一句话:基础不牢,地动山摇,基础不稳,做题不准

二刷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一下,仍然没有任何效果
  • 删除时比较慢,删了接近两个小时,但是count表数据总数时非常快,毫秒级别
    • 感觉这就算是空间换时间的意思?
  • 这张表除了id外没有索引,在有对应字段索引时$gt查询效果会如何呢
    • 抽个时间造个100万条试试,毕竟连alpha的机器人每天都要塞千万级的数据进mongo呢。。。
  • 查询时,对一个属性正则匹配,对另一个属性使用$gt,这两者的排列顺序是否会影响查询的效率?

本文链接:https://smallpath.me/post/cut-2016-hand-12

-- EOF --