Promise 改造 child_process.exec

`util.promisify(child_process.exec)` 得到的函数无法获取 `exit code`,所以我重新封装了一下。

child_process 是 Node.js 的一个内建模块,用于分裂出(spawn)一个子进程,执行一些特定操作。.exec() 是它的方法,接受一个参数,即要执行的 shell 命令,然后通过回调返回结果。.exec().spawn() 的不同之处在于,前者重在返回结果,后者则重在返回内容。所以当你需要执行一个命令,你并不关心执行过程中发生了什么,只要看到结果就好,那么就用 .exec();反之,假如执行过程中产生的信息对你特别有价值,你并不是特别在意结果,就应该用 .spawn()

另外,我之前在《Node.js 8 中的 util.promisify》中介绍过,Node.js 8 引入了一个新函数,位于 util 模块,叫做 promisify(),用于将回调风格的 Node.js 函数改造成 Promise 规范的函数。

OK,背景知识介绍结束。近期开发中,我需要执行一个命令,并且取得它的 stdoutstderrexit code,使用 promisify() 之后发现没有 exit code,于是只好重新写了一下,代码如下:

import {exec as BaseExec} from 'util';

function exec(command, options) {
  return new Promise((resolve, reject) => {
    let result = {};
    const cp = baseExec(command, options, (err, stdout, stderr) => {
      if (err) {
        err.stdout = stdout;
        err.stderr = stderr;
        reject(err);
        return;
      }

      result.stdout = stdout;
      result.stderr = stderr;
      if ('code' in result) {
        resolve(result);
      }
    });

    cp.on('exit', (code, signal) => {
      result.code = code;
      result.signal = signal;
      if ('stdout' in result) {
        resolve(result);
      }
    });
  });
}

希望对大家有用。

新键盘到了,FC660C,静电容,试用一下,效果还不错。略硬,段落感不强,声音不大。

尬聊会:第十一期

尬聊会第11期实录。介绍了学会背锅学会汇报;变黑锅为机会;纯CSS校验表单的相关知识。

视频在此:尬聊会第11期 学会背锅学会汇报=升职加薪/变黑锅为机会/纯CSS校验表单

时间:2018-07-01 20:45
地点:我的斗鱼直播间 douyu.tv/meathill
回看视频:http://blog.meathill.com/tech/galiao-11.html

0. 学会背锅,学会汇报——升职加薪的阶梯

我们(80s)被教育要谦虚谦逊低调,隐藏自己的真实想法和目标。

在学校

  1. 不主动当班干部
  2. 不主动加入学生组织

职场上

  1. 我们保证自己能够决定自己的得失
  2. 确保你处在一个健康的商业环境里

如何判断当前的商业环境是健康的,还是不健康的呢?

  1. 看这家公司是“规矩”大,还是“老板的态度”大

学会汇报

  1. 周期,按时提交报告
  2. 确定里程碑时间点
  3. 报告里要尽量携带数字
  4. 结案的时候一定要主动汇报

1. 如何防止产品在临时上线前突然地改需求(这个需求可能是功能也可能是UI交互)?

  1. 作为前端,有必要理解产品和需求
  2. 在开发的时候,保持自己思路跟着产品走,力求从中发现问题
  3. 如果产品上线之前,环境发生了比较大的变化,就坦然接受

2. 表单验证

学习正则

正则表达式30分钟入门教程 http://deerchao.net/tutorials/regex/regex.htm

codepen

MDN:https://developer.mozilla.org/en-US/docs/Web/CSS/:placeholder-shown

实录地址:

2018-07-01 尬聊会 第11期实录


欢迎加入肉山小课堂一同学习,QQ 群:肉山小课堂答疑交流群 628056148,SF 圈子:肉山小课堂继续深造中心

代友内推:【北京】【教育】【前端】【上市公司】

朴新环球教育
招聘前端开发工程师

[工作职责]

  1. 负责公司业务项目(后台系统)的前端界面开发和逻辑实现;
  2. 根据产品需求,实现产品界面和交互功能,页面维护及性能优化;
  3. 负责现有产品的持续改进

[任职资格]

  1. 2年以上Web前端开发经验,计算机相关专业优先
  2. 熟练掌握HTML5、CSS3、JavaScript、jQuery等,有较强的代码能力
  3. 熟练使用至少一种JS框架,熟练Reactjs、Angular、Vue等,能独立开发常用组件
  4. 对前端工程化、模块化开发有一定了解,熟悉 gulp, webpack等,有开发经验优先
  5. 熟悉Java,node等后端技术优先 ;
  6. 善于沟通,工作积极主动,责任心强,具备良好的团队协作能力。

薪资open 面谈
联系人王军武 ‭136 9100 7757‬
邮箱 wangjunwu@pxjy.com

记第一次怼厂长

最近做 N 项目,被厂长批评好几次效率低,终于忍不住在周会上怼了厂长。记录一下,将来说不定还会怼,或被怼。

最近做 N 项目,被厂长批评好几次效率低,终于忍不住在周会上怼了厂长。记录一下,将来说不定还会怼,或被怼。

1. 我不会 Perl,Perl 也比我想象的难学

我会三门语言:JavaScript、ActionScript、PHP。我学它们的时候并没有投入太多时间,所以我这次也是用差不多的态度对待 Perl,结果完全不一样。Perl 是一种非常灵活的语言,我觉得它有些过于灵活。它里面很多 $.$_ 这样的东西,用起来很爽,不懂的时候看起来就火葬场了。

所以我花了比想象中更多的时间去学习 Perl。这一点算我的问题,我对此没有异议。

2. N 项目交给我时架构很初级

也许和厂长想的不同,在我看来,N 项目交给我们时,就是一个原型,架构非常简单非常难看,我最多给它打30分——厂长可能觉得有60分吧。所以本来就不会 Perl 的我面对这样一个极差的架构就更头痛了。它的架构差表现在:

  1. N 项目是典型的面条形代码,从头到尾一个逻辑写完,4k行
  2. 由 Perl 和 JS 两种语言混编构成,缩进完全混乱,变量乱插
  3. 任何一个功能,都要在 4K 代码中找到若干处修改,没有指导文档,没有设计模式

所以开发它会遭遇很多计划之外的问题。

3. Code Style

在混乱的架构下,厂长对 Code Style 的要求也非常严苛,他会一一挑出来少空行的地方少空格的地方要求修改。

这对我来说本不成问题,我当然同意我们应该遵守同样的语法规范,但是,我接手时的 Code Style 就已经混乱不堪。作为一名老程序员,我第一件事就是学习他的规范,每当我遇到换行、空格犹豫不决的时候,就会去找类似的代码,然后照着他的代码写。结果提交后被多次指责没有遵守规范。这叫好比,生活委员来查寝,然后指责你们寝室脏乱差,要扣精神文明分,继而影响评优,然后你去他寝室一看一样脏乱差的一比。

另外,无论再小心,笔误也是难免的。所以 Code Style 这种东西理应交给 Lint 工具来做,这样,交付给新人的代码,新人完成的代码,都能保证遵守规范。而不是像现在一样,每天早上起床看 review comments,一堆换行空格的问题,满满的负能量。


其实还有对前端的认识问题,下次再怼吧。

表单元素 disabled 的判定

判断一个表单元素是否为 disabled,应该使用 `.matches(‘:disabled’)`。

测试需求,判定表单元素是否 disabled。

看起来很简单,直接在浏览器控制台里用 $('input[type="text"]) 选中一个 <input>,验证一下它的 disabled 属性,没问题,于是就直接写成:

function isDisabled(element) {
  return element.disabled;
}

后来做到一个用户权限的功能,某一类用户,可以看到某些设置,但不能改。为了省事,就直接 禁用这部分表单。同时,因为我们用 <fieldset> 包装表单元素,于是我就把 disabled 加在 <fieldset> 上,这样可以不需要修改每个元素。

结果测试的时候就失败了,JS 认为这些元素不是 disabled,但视觉上和操作上它们的确被禁用了。于是调试,发现这些元素的 disabled 的确为 false,但是它们可以 .matches(':disabled'),Google 之,StackOverflow 的几个问答也是同样的结果。

于是将前面的函数改成

function isDisabled(element) {
  return element.matches(':disabled');
}

进一步的,我检查了其它几个属性,包括 readonlyrequired,发现 <fieldset> 只支持 disabled

开发 WordPress 的 nginx 配置

整理两个开发 wp 的常用文件。

以前比较习惯放在 /etc/nginx/ 里,用 service nginx start 启动(对应 MacOS + brew 就是 /usr/local/etc/nginx/brew services start nginx)。来到我厂后,开始频繁接触 Nginx 和 OpenResty,现在觉得单独放在目录下面比较方便管理,所以改了一个出来。

配合 Makefile,方便日后使用:

  1. 启动服务 make run
  2. 关闭服务 make stop
  3. 重新加载 make reload
  4. 使用 php-fpm
  5. 代理上传资源(/wp-contents/uploads/)到真实服务器
  6. log 在本地
nginx = nginx

.PHONY: run
run:
    mkdir -p logs
    $(nginx) -p $$PWD -c nginx.conf

.PHONY: reload
reload: logs/nginx.pid all
    $(nginx) -p $$PWD -c conf/nginx.conf -t
    kill -HUP `cat $<`

.PHONY: reload
stop: logs/nginx.pid
    $(nginx) -p $$PWD -c conf/nginx.conf -t
    kill -QUIT `cat $<`
error_log logs/error.log error;
pid logs/nginx.pid;

events {
    accept_mutex off;
}

http {

    server {
        listen 9010;
        listen [::]:9010;

        include /usr/local/etc/nginx/mime.types;

        root /Users/meathill/Sites/wp-dev;

        index index.php index.html index.htm index.nginx-debian.html;

        server_name wp-dev.com;

        location / {
            try_files $uri $uri/ /index.php?$args;
        }

        location /wp-content/uploads/ {
            proxy_pass https://blog.meathill.com/wp-content/uploads/;
            proxy_set_header Host blog.meathill.com;
            proxy_ssl_name "blog.meathill.com";
            proxy_ssl_server_name on;
        }

        location ~ \.php$ {
            include /usr/local/etc/nginx/fastcgi.conf;

            fastcgi_pass 127.0.0.1:9999;
        }
    }
}

代码放在 Github wp-dev-env

2018 NBA 总决赛

只要詹姆斯不得总冠军,我就觉得比赛好看,哦也。

今天勇士干脆利落的干掉了骑士,总比分4:0横扫对手,夺得总冠军。如果看过比赛,就知道双方实力差距之明显,裁判相帮都帮不了。

我拾起来看球大约是2009年,科比二连冠的之前。作为乔丹的球迷,其实我一直不太喜欢科比,因为在乔丹重回 NBA 时,科比是看起来最拼命想把他拒之门外的人。大学期间,NBA 变得丑陋,活塞和马刺两支球队总决赛可以和砍 150 分,少年人怎么可能喜欢这样的比赛。没记错的话,那也的确是 NBA 收视率最低迷的时候。——当然工作几年之后,我也开始喜欢马刺。

接下来,拯救联盟的所谓第一人出现了,自然,我在说詹姆斯。联盟非常希望再出一个乔丹,好好提升一下 NBA 的地位,和收视率,于是对詹姆斯寄予厚望。——科比因为鹰郡丑闻,以及奥尼尔出走之后战绩平平,当时被联盟、赞助商集体抛弃。这是我不喜欢詹姆斯的原因:早年的他太依赖身体和裁判。

依赖身体没问题,天赋异禀总不可能自断双腿吧。但是依赖裁判就让人很烦。首先,比赛变得破碎,因为罚球很多;其次,詹姆斯技术太粗糙,走步走得太夸张,以至于被大家戏称“蟹皇”;再其次,一个新人,即使深孚众望,但群众基础仍然薄弱,看到自己喜欢的球队球星被亲儿子暗算,谁都会心生不爽。

联盟没想到的是,篮球不会说谎。詹姆斯贵为亲儿子,也免不了被焦作人。反倒是之前的弃子科比,因为奥运会的关系,在中国的巨大人气一下子惊到联盟和赞助商,再加上球队的出色运作,一跃而成 23vs24 中的胜者,勇夺两连冠。可惜好景不长,三少横空出世,接着詹姆斯令人不齿的 The Decision,虽然老牛奋蹄让很多人再次相信爱情,但仍难以避免商业展现自己尖牙利爪——詹姆斯终于统治了联盟。

于是我又弃番。

再次拾起来便是因为库里和勇士。水花兄弟和炮轰战术实在太赏心悦目了,一下子把观赏性大幅提升了一个档次。每次看似不可能的出手,都让人兴奋不已。

可惜,2016年詹姆斯从格林身上跨过去的那一脚,再次改变了历史——詹姆斯还是那个最恶心的亲儿子。


今年第一场,勇士果然被詹姆斯打了个措手不及,险些被偷走一场胜利。没想到 JR 生生把詹姆斯偷到的果实给送了回来。

第二场没什么异常,勇士碾压获胜。

第三场,理论上主场 2:0 领先,这一场都要浪一下,让一把。一来给对方些面子,二来多卖一场门票,三来回头主场夺冠好庆祝。所以上下一心,从裁判到球员,都一副要让骑士赢的样子。只有一个人不乐意:杜兰特。

杜兰特输不起,他比詹姆斯还输不起。詹姆斯最多算是“抱团”,迈阿密大当家虽然没有明确排座次,但实际上是他的。杜兰特是来抱大腿的,他来之前勇士已经总冠军、73胜、实力强于对手。杜兰特只是锦上添花。所以一旦输了,那真的颜面扫地。

所以杜兰特紧咬牙关,力拼争胜。骑士就是这么烂,对方一队都在让,裁判拼命在帮,但只要对方一名当家球星不想让,就赢不了。

至于第四场,和第二场一样,只要勇士想赢,骑士怎么反抗都没意义。

可惜库里最后没拿到 FMVP,不怪 KD,只怪对手太菜,以及,库里代言安德码。


希望勇士保持阵容整齐,这么漂亮的打法,我还想多看几年。


詹姆斯之所以讨厌,还有一点:他的团队特别喜欢把他塑造成孤胆英雄,反映在詹扑的球迷都这德性。无论走到哪儿,都必须是单核,历史带队第一人,无限贬低队友,所有功劳都是他的。赢球居功至伟,输球队友 CBA。以至于队友公开说羡慕勇士,尼克杨9中1仍然可以高高兴兴准备下一浪,自己连续俩不中就准备帮大佬背锅。

所以为啥欧文要走?很多人不理解。不是跟着詹姆斯打不到球,或者打不了总决赛,是实在不想帮丫建功替丫背锅。明明当年靠我抢下的胜利,尼玛最后都算给詹姆斯了。你看人家马刺,明明邓肯还在场上贡献着无与伦比的表现,该移交大旗就移交了。什么叫我不给的你不能抢?太tm把自己当回事了。

詹姆斯是不是第一人?是。但他为什么是第一人?因为联盟、团队都在把他塑造成第一人。就像李某来,先号称自己是比特币首富,然后通过收割韭菜成为(有可能的)比特币首富。在我看来,詹姆斯并不是靠自己的能力成为联盟第一人,其实力远低于乔丹和科比,也低于奥尼尔、邓肯、诺维茨基,更低于库里。但因为他的定位是第一人,所以他的表现是第一人。典型的“规则玩家”。

所以詹姆斯必须感恩,必须把功劳让出去分出去,因为“历史第一人”是人设,不是拼出来的。就这样。

倒霉邻居

邻居搬来一家人,经常出问题,让我不由得不为爸妈担心。

前几天送孩子回老家,跟老妈聊天,得知旁边搬来一家人,一个妈妈带一个小孩,小孩一岁多,会走路不会说话。妈妈白天要上班,就从老家把她妈请来了。她妈是典型的农村老太太,极度节省,没事就到处拾破烂,然后坐在走廊里收拾破烂。这倒也能忍,毕竟我们家也不是什么富贵之家,周围邻居基本都是市井小民,早就习惯了。

但是有两件事让我很不放心。

  1. 有一天,老太太出门拾破烂,小孩子自己就跑出来,后来摸到楼梯,然后就摔倒了,滚了半层楼,头都磕破了,后来被我爸发现,送到家里。

2.

又有一天,我爸妈在家里闻到强烈的焦糊味,找不到来源。中午他们要去奶奶家做饭,出门的时候发现楼道里全是烟,都是从她们家冒出来的,原来是小孩子不知道怎么把门打开了。我爸妈走进去一看,火上滚着一锅稀饭,里面已经烧干了,锅都烧红了,我妈赶进去关火,还把她手烫了一下。

然后我爸先去做饭,我妈在她家等着,等了10分钟老太太才回来,果然又去拾破烂了。我妈把她骂了一通。


补充一下,我家房子所在小区一般,密度比较大,一层7户,除了两头户型大一些,中间5户都是比较小的户型,所以住进来的大多数是低收入群体。

总之,买房要谨慎,尽量买自己能力范围内最好的房子。

服务器备份工具

目前维护着几个服务器,所以需要一个备份工具帮忙备份。本文记录一下需求。

目前维护着几个服务器,所以需要一个备份工具帮忙备份。因为都是 wordpress,所以

  1. 可以访问 wordpress 的安装路径
  2. 可以部署在服务器上
  3. 最好是 PHP,方便 require wp-config.php

备份的内容:

  1. 备份数据库,直接访问 wp-config.php 就行
  2. 备份 wp-uploads,这里要支持差异化备份了
  3. 备份服务器配置,包括:
    1. php 配置
    2. nginx 配置
    3. crontab 配置

备份的处理:

  1. 每次备份的内容打一个压缩包,命名为 服务器-站名-日期-时间.zip
  2. 将备份后的内容上传到指定服务器
  3. 还需要开发一个本地工具,用来从制定服务器上下载备份文件到本地(服务器存储有点贵)
  4. 自动删除半年前(可配置)前的备份文件

差不多这样,想起来随时补充