作者: meathill

  • Node.js 8 中的 util.promisify

    Node.js 8 中的 util.promisify

    Node.js 8 于上个月月底正式发布,带来了很多新特性。其中比较值得注意的,便有 util.promisify() 这个方法。

    如果你已经很熟悉 Promise,请继续往下看。如果你还不熟悉 Promise,可以先跳过去看下下章:Promise 介绍

    util.promisify()

    虽然 Promise 已经普及,但是 Node.js 里仍然有大量依赖回调的异步函数,如果我们把每个函数都封装一遍,那真是齁麻烦齁麻烦的,比齁还麻烦。

    所以 Node.js 8 就提供了 util.promisify() 这个方法,方便我们把原来的异步回调方法改成支持 Promise 的方法,接下来,想继续 .then().then().then() 搞队列,还是 await 就看实际需要了。

    我们看下范例,让读取目录文件状态的 fs.stat 支持 Promise:

    const util = require('util');
    const fs = require('fs');
    
    const stat = util.promisify(fs.stat);
    stat('.')
      .then((stats) => {
        // Do something with `stats`
      })
      .catch((error) => {
        // Handle the error.
      });
    

    怎么样,很简单吧?按照文档的说法,只要符合 Node.js 的回调风格,所有函数都可以这样转换。也就是说,只要满足下面两个条件,无论是不是原生方法,都可以:

    1. 最后一个参数是回调函数
    2. 回调函数的参数为 (err, result),前面是可能的错误,后面是正常的结果

    结合 Await/Async 使用

    同样是上面的例子,如果想要结合 Await/Async,可以这样使用:

    const util = require('util');
    const fs = require('fs');
    
    const stat = util.promisify(fs.stat);
    async function readStats(dir) {
      try {
        let stats = await stat(dir);
        // Do something with `stats`
      } catch (err) { // Handle the error.
        console.log(err);
      }
    }
    readStats('.');
    

    自定义 Promise 化处理函数

    那如果现有的使用回调的函数不符合这个风格,还能用 util.promisify() 么?答案也是肯定的。我们只要给函数增加一个属性 util.promisify.custom,指定一个函数作为 Promise 化处理函数,即可。请看下面的代码:

    const util = require('util');
    
    // 这就是要处理的使用回调的函数
    function doSomething(foo, callback) { 
      // ...
    }
    
    // 给它增加一个方法,用来在 Promise 化时调用
    doSomething[util.promisify.custom] = function(foo) { 
      // 自定义生成 Promise 的逻辑
      return getPromiseSomehow(); 
    };
    
    const promisified = util.promisify(doSomething);
    console.log(promisified === doSomething[util.promisify.custom]);
    // prints 'true'
    

    如此一来,任何时候我们对目标函数 doSomething 进行 Promise 化处理,都会得到之前定义的函数。运行它,就会按照我们设计的特定逻辑返回 Promise 实例。

    我们就可以升级以前所有的异步回调函数了。

    (更多…)

  • 笔记本坏了

    笔记本坏了

    从前司离职之后,买了台 XPS-13 作为日常外出办公用机。结果61那天,不知道怎么回事,突然出问题了,表现为:

    1. 开机后,提示硬盘有问题,请重启修复
    2. 大部分软件没问题,有些文件打不开,同时打开“文件资源管理器”变得特别慢,有点像我上一次坏硬盘的状态
    3. 重启后会修复,但是修复到100%就会蓝屏死机,然后重启
    4. 然后进入 Dell SupportAssist 界面,扫描后说一切正常,但是找不到启动设备,只能关机
    5. 按任意键跳过检测,可以进入系统,问题照旧

    (更多…)

  • 第四,第五次直播总结

    第四,第五次直播总结

    之前完成了第四次直播《写 CSS 也要开脑洞:万能的 :checked + label(后面简称 “CSS 脑洞”)和第五次直播《实战组件开发——手机日历 – 1. 项目启动》(后面简称“实战手机日历1”)。

    CSS 脑洞卖的还可以,基本上跟 Promise 差不多,比较符合我的预期,慢慢成长呗。不过实战手机日历1就卖的很差,无论实售还是在线人数,几乎都创下历史新低……

    事后我也在群里调查了一下,截至到目前,有两位表示大周末的不想学习,有两位表示时间太久消费太高(其中一个是学生,倒也可以理解),有两位表示觉得内容不感兴趣。

    我个人觉得,单纯从干货角度来看,CSS 脑洞当然是最丰富的,6个实例,几乎都是拿去就能用的。而且相当开拓视野,能卖的好我觉得正常。但是实战1其实做的也不太差,至少在斗鱼试播的时候,围观群众中有两位当时就下单了。

    至于周末嘛,也有大大在周末搞,好几百人来听的,所以,也不能完全赖周末。

    换跑道果然还是很困难呀……总之,继续努力,先把这个系列做完!

  • 流程那些事

    我司越来越大了,跟小孩子一样,讨人厌的部分也越来越多。一群没搞过互联网的人混到各种高高低低的位置上,遇到看不懂的问题,第一反应就是套用以前的经验,提来提去,最多的就是流程控制。今天就聊两句流程。

    先说好处。

    第一个,降低培训成本。对于岗位齐全的公司来说,大部分工作都需要多部门配合,共同完成。资深员工处理熟悉的问题多半问题不大,新人或者新需求就难办了。这时,固定的流程可以大大简化这个过程,只需要对照12345,依次推动相关部门,基本就能解决。

    降低沟通成本。很多工作步骤都需要先决条件,前置工作没完成下一步根本没法展开。流程要求执行人必须严格按照事先约定的步骤去推动各环节,防止执行过程前后矛盾互相打架以致浪费时间。

    责任到人,有利追责。没有流程限制,有些人会想出各种法子逃避工作,或者拖延工作。流程固定之后,该是谁就是谁,跑不了躲不掉。另外出了问题,沿着流程向上追查,总能找到出问题的环节,到时候其他按规定完成自己步骤的人不需要一起担责任,也是应该的。

    方便电子化。形成标准化流程之后,再将其电子化,又能大大提高效率,而且方便管理、统计。

    接下来是缺点。

    流程是死的,事儿是活的。很难制定出又具有弹性又具有约束力的流程。一旦流程本身有问题,这条线上所有人要么一起担责任(理想状态),要么大家都撒手不管。为了能适应各种真实场景,管理人员不得不逐步给个别环节松绑,后来难免使得流程压向其它环节,造成其他环节人员的不满。

    在完成与没完成之间,其实有着非常宽的灰色地带。流程强调的是人人都完成工作,但实际上,完成90分,和完成50分,区别可大着呢。那么增加审查环节么?科学与否暂且不说,所有环节都审查本身成本也太高。流程导致这条线索上的所有人,不再以效果来获得评判,而是以是否按时完成工作,对真正努力的人是一种伤害。

    扼杀创新。创新本质就是突破常规,寻找现实中的束缚,找到甚至创造条件打破它。于是创新本身就是反流程的。当某些员工想到了创新的点子,却困于既有流程没法实现,便会产生巨大的挫败感。——那位说我们制定一个流程来规范创新不就好了?对不起,请去跟那些被互联网公司杀死打残的传统大公司说吧。

    迷恋流程使得处处皆流程。几乎没有什么工作是不能流程化的,喜欢流程的人总能找到各种理由推动新流程的制定。到后来干什么几乎都要流程,干什么都很麻烦,最后干脆就什么都别干,少干少错。

    我的看法。

    流程是个好东西,很多时候使用流程能极大改善效率。但必须认清流程也有副作用,不该设置流程的就不要流程。

    哪些适用流程呢?

    操作化的,变化条件比较少的。

    哪些不使用呢?

    创造性的,流程复杂多变的。

    不设计流程,怎么保证业务开展高效实施呢?很遗憾,我的专业不是管理,我也没有看到过令我信服的答案。但是在我看来,互联网企业天生具有这方面的优势。

    首先,公司小,人少,大部分工作是少数人就能完成的。所以沟通成本本来就低,不依赖流程靠碰头会只要有智商够的人牵头基本都能完成。其实我司之前一直如此,只不过这样老板会觉得不安全,觉得太依赖某人,自己缺乏掌控。

    其次,本来就有很多事情可做可不做,大公司闲人多,那就多做多说;小公司,不得不把视线聚焦到最值得做的事情上。这个时候,流程不再是保障,没有流程自然也无所谓。

    最后,互联网公司本来就靠攻击传统大公司的软肋创造生存空间,这需要大量的创新,和各种基于逻辑推理的冒险,流程在这中间扮演的反而是反面角色。没有刻板的流程限制让互联网公司广阔天地认我傲游,从而成就一番伟业。

    最后说回我司。我从公司创立半年后加入,直至今日,倾注了大量的心血,投入了大量的感情。其实我既不反对设置流程,也不反对执行流程,只是结合我之前吐槽我司的那些文章来看,我司很多人其实并不具备服务精神,不具备在一家互联网企业工作的思想准备

  • 系统性学习与碎片化学习

    系统性学习与碎片化学习

    4-27在小密圈接到第一次付费提问,喜获8块。庆祝一下。

    这个话题也是我在小密圈里和那位同学的交流时产生的。他说他“学习的知识也不系统化”,“学习的知识也比较混乱”。“不系统”暂时没有好办法,但比较混乱一定是个问题,但是几句话说不清楚,所以构思了半天,准备写一篇文章来回应。


    TL;DR: 中心思想:

    我们以前熟悉的,以学校培训为主要形式,所谓“系统性学习法”,很难适应新时期互联网开发的需求。我们必须掌握碎片化学习法,即在快速建立起基础知识体系后,利用碎片时间,有目的有针对性的吸取专业知识,将其拼接到知识体系之上。使自己能够快速成长,在需要的时候还能及时切换学习方向。

    (更多…)

  • 《写 CSS 也要开脑洞:万能的 `:checked + label`》视频补缺

    《写 CSS 也要开脑洞:万能的 `:checked + label`》视频补缺

    4月27日直播《写 CSS 也要开脑洞:万能的 :checked + label》时,OBS 推流连接断了一下,当时不知道情况,今天看了下发现录像中间少了6分钟多的内容,虽然不是最关键的部分,不过还是补一下吧。

    不过这段视频 5:50 的位置,介绍纯 CSS 组件的优势那里有问题。当时有点忘词,这里我想说的第一点是:

    纯 CSS 组件顾名思义,只改变外观,不改变行为。所以它的功能不会因为浏览器变化而变化,即使浏览器支持不完善,即使因为加载速度或者网络关系,导致 CSS、JS 加载失败,它最多样式回归到原始样式,功能是完全一致的。在非标准浏览器环境下,如读屏器,也是如此。

  • 看看前端技术的发展动态,我们似乎应该重新规划学习方向

    看看前端技术的发展动态,我们似乎应该重新规划学习方向

    这个标题是仿照好奇心日报起的。

    近期在帮朋友招聘,目标是找到一个可以独立工作,能够应对大多数问题的前端。初筛简历的时候我比较偏爱之前经历大多是 JS 开发的候选人,比如专门写插件的,或者写过游戏的,对接的同学就问我:前端是不是做过游戏有加分?其实也不完全如此,只是由于环境的变化,JavaScript 开发在前端的整体工作中占据着越来越为大的比重。以前那种先考察切页面能力的做法已经完全不适用了。也导致,我们在前端学习上,需要重新调整侧重点。

    创造 HTML 的目的,是为了阅读文献,从 HTML 标签当中我们就能看到很多来自于印刷时代的痕迹,比如:

    1. 各种语义化的标签 <p> <h1> <h2> <blockquote>
    2. 以竖排版为主的格式
    3. 丰富的字体选项

    浏览器也是朝着这个目标去实现的。于是,早期浏览器在界面布局上做的并不好。伴随着互联网发展,越来越多的用户涌入,他们要求互联网以网页为载体,提供更多满足他们需要的产品。此时最早一代 HTML 和 CSS 就不那么适用了。在我开始做前端的那个年代,经常会碰到各种各样奇奇怪怪的问题,写出来的代码,很难达到自己的预期。于是,做前端,最重要的积累,就是各种浏 Hack,什么清浮动啊、IE6 啊,差不多就是这些。

    这些东西往往并无逻辑可言,所以,老前端比新前端的优势,就在于记住了多少这方面的经验,解决过多少这方面的问题。我们招聘的时候,也倾向于选择有丰富页面制作经验的,毕竟,编程问题很多时候归属于后端。

    然而时过境迁,我们现在再去看前端技术,它的现状和趋势已经都变了。首先,越来越多的浏览器,都在遵守 W3C 规范,我们现在已经不需要再拿那么多时间去做 Hack。浏览器之间的差异,已经从实现的差异(比如 addEventListenerattachEvent),变成了功能化的差异(比如是否支持 Grid 布局)。所以在这个时候,知道多少浏览器 Hack ,也不再是优势。

    另一方面,越来越多的工具涌现出来,我们大部分时间都在使用脚手架、预处理工具、模板引擎,已经很少直接手写最终的 HTML、CSS 代码了。再加上 MVVM 框架对整体工作流的影响,如今,使用命令行,已经是前端必修课。所以,扎实的编程基础,丰富的,在各种环境下进行调试的经验,都是高级前端工程师真正的竞争力所在。

    总结一下,现在切页面变得相对容易,大多数览器的表现都会和预期一致。所以哪怕相关经验差一些,现学也很快。但是开发经验,如果没有积累,想在短时间内快速提升到能够独立应对大多数需求的水准,就比较困难。所以前端应该尽早关注 JavaScript,尽量多的尝试各类基于命令行的工具,甚至主动跨出舒适区,自己动手实现一些工具。这些会对将来的工作,对将来应聘,带来很多好处。


    参考资料:

    1. wiki HTML
  • 面试经:GitHub

    面试经:GitHub

    GitHub 越来越有名,很多同学都把它作为一个关键字加入自己的简历当中。不过我在面试中,问到如何使用 GitHub,对方通常会答复:上去看源码呀!这个答案完全无法让我满意,具体的原因,一方面可以参考我之前的一篇文章《谈学习:读源码》,源码不是小说,直接看源码收获太小。另一方面,看源码是一个太直接的逻辑推断——上面有源码所以我去看源码——我不认为这是一个细心耕耘慢慢养成的习惯。

    接下来我想简单谈一下,我认为应该如何使用 GitHub。

    Issues 和 PR

    一个 GitHub 仓库可不仅仅是一份源代码那么简单。GitHub 是开发者社交平台,所以每个项目在代码之外,都会有两个非常重要的模块:

    1. Issues 问题,包括 Bug,和其它使用者希望有的功能
    2. Pull Requests(PR) 其他的开发者在这个项目上做出了一些改进,或者修复了一些 Bug,希望能够合并到 master 当中,就会发起 PR

    完美的代码是不存在的,越是用的人多的库,存在的问题,或者说被发现的问题可能就越多。阅读其他人提的问题,很多时候可以获得不小的收获,比如,大家开发时都遇到了什么问题?有没有与我类似的情况?他们是怎么解决的?大家最想要的新功能是什么?有哪些值得关注?我能做什么?等等。

    以及,可能是更重要的,我们应该怎么样通过 Issues 与仓库的原作者进行交流。

    毕竟我们每个人的时间都是有限的,对于大部分开源的类库来说,了解怎么用、有哪些问题、怎么避免踩坑,通常会比你知道它某个函数是怎么写的更有价值。

    看文档

    好的开源类库通常还会有一个做得非常到位的地方,便是它们的文档,做得通常详尽有价值。通过阅读文档,可以很快的了解这个仓库是干嘛用的,应该怎么用,能解决哪些问题,以及接下来,它的发展方向是怎样的。

    据我观察,文档通常分布在三个地方:

    1. README.md,也就是打开仓库页面,默认渲染在文件列表下面的那块
    2. 官方网站,通常在导航下方,仓库简介那里
    3. wiki,通过导航链接可以到达

    观察提交频率

    并不是所有的仓库,都有开发者在进行积极地开发和维护。如果搜索到几年前的文章,被导引到一些比较古老的仓库,可能出于某种原因,已经没人对它进行维护了,这个时候,该放弃就要放弃。

    人生苦短,时间有限,总会有更具价值的仓库供我们学习。

    GitHub 热门趋势

    GitHub 还有一个热门趋势页面,从中你可以了解到全世界的开发者都在关注哪些仓库,你可以把自己感兴趣的那些加星标记一下,将来不定时的翻一翻看一看它的 Issue、PR 和文档,通常都会有不小的收获。

    GitHub Pages

    GitHub 还提供给我们一个非常好的静态网站空间,完全免费,全世界都有 CDN,不用白不用。便是传说中的 GitHub Pages。

    我们可以用它写博客,做笔记,重点是内容完全可以进行版本管理。

    具体做法请自行 Google。

    不要放弃提交自己的仓库,也应积极向别的开发者提出 Issue 和发起 PR

    我觉得这件事和写博客一样,如果你只是在纸上记笔记给自己看,那多半会不求甚解;但是你想到写成博客总会有人看到,那多半还是会把要写的内容搞清楚,写全面,逻辑清晰可自洽。所以写博客是比记笔记更好的学习方法。以此类推,把自己的仓库推到 GitHub,也理应也是比在本地练习更好的学习方式。

    这里绝不鼓励大家乱来,相反,我希望大家对自己的行为负责,重视 Issue 和 PR,毕竟都是提给其他开发者的,或多或少都会对别人造成影响。所以在提之前,十分有必要阅读仓库主人的提交须知,按照对方的代码规范书写代码,写好相关测试,然后再提交。做到言之有物,切不可乱来画猫。


    总结

    这篇文章不是传授大家应聘技巧的,而是希望分享自己的一些经验,让大家能够通过 GitHub 这个世界上最大的代码托管平台,正确的学习开发技巧。

    如果您有相关的经验技巧,欢迎交流。

  • 第三次直播总结,兼谈技术教学

    第三次直播总结,兼谈技术教学

    前几天完成了第三场直播:《Web 永恒不变的主题:布局——Box,Flex,Grid》,这里总结一下。

    坦率的说,第二场直播给我造成了一些错觉。因为第二场直播比第一场多了十个人,差不多1/3,让我以为自己取得了不小的进步,甚至上一次总结的时候还信心满满。然而,这一场观众数又给我干了回来,甚至还不如第一次。感觉尚未稳固的信心又失去了……

    尤其是,第二场开播之前,有将近40个人加入我开辟的答疑群,这个人数几乎和购买课程的人数相等。但是第三场,前后只有不到10个人加了进来。我只能自我安慰,告诉自己,很多人之前已经加入了……

    从准备的充分程度来说,第二场 Promise 的 N 种用法,应该是最充分的。但是从技术的实用角度来看,第三场 CSS 布局应该也不差。而且理论上,CSS布局更基础,来听的人应该更多才是——我只能认为,Promise 解决的异步回调问题,比 Grid 解决的复杂网格布局,更重要,更有价值,

    希望下一场会好一点吧!

    接下来谈两点想法。

    干货

    从选题开始,我就不想讲什么个人发展,或者前端技术展望之类的。我不是说这个主题不好,我只是觉得这个对听众来说用处不大。如果听众是一个自我驱动非常强、喜欢技术、喜欢开发的人,我相信他应该很容易找到类似的信息,清楚自己的前进方向;相反,如果用户还比较迷茫,只是试探性的踏入这个领域,听了意义不大。

    因为,之后真正的学习,会耗费大量的时间,这个时候就不是听听故事便足够了,而是需要个人反复练习。另一方面,每个人的情况不一样,想要制定合适自己的学习计划,恐怕只有一对一的交流,才能产生真正的价值。

    总而言之,我决定只讲干货,也就是用户听了,他就会了,按照我讲的思路,12345,上手就能干活。我认为如此一来,多学多练,构建起自己的技术体系,比听别人的故事收益更大。至少,我当年就是这么学的。

    但是就结果来看,我的课卖的并不好。我觉得跟我自身品牌有很大关系,还是要继续积累。上次课讲完,有个同学找到我,说觉得我的课更干货,鼓励我坚持下去。其实这个时候听到这样子的鼓励,心里还是挺暖的。

    道 & 术

    上次直播到问答时间,立刻就有同学提问一个我认为我已经说清楚的问题,或者说,我PPT里明确讲到的问题。对此我也进行了反思。

    我当然不会认为是同学没有认真听讲,大家都是花钱来的。反省之后,我认为,在讲述的过程当中,我想传达的是“道”,也就是所以然;但是很多同学,因为经验问题,因为视野问题,他可能只想听“术”,也就是然。

    从备课的角度来说,我一定要做到逻辑自洽,不仅要讲明其然,还要讲明其所以然。所以在实践过程中,我可能更关注的是讲明其所以然,也就是原理,回归到规范、定义、浏览器实现等更基础的地方;但是听众想知道的很可能是具体操作。比如布局,我会讲,外层元素没有被浮动的子元素撑开,是因为外层元素没有触发独立的 BFC,然后 BFC 是 XXOO,所以你这个时候要想办法触发它的 BFC;但是听众其实更关心“高度塌陷”怎么解决?浮动怎么清?BFC 什么的一下听不懂就整体忽略掉了。

    这是我日后需要注意的地方:减少掉书袋,讲好What How Why。


    最后给下一场打个广告。

    写 CSS 也要开脑洞:万能的 :checked + label 将于4月27日,下周四,晚上8点直播。这场课程,是既有基础,又有进阶的中级课程。相信会对大家有所启发,欢迎大家光临。