loveky的流水账

如果你像我一样办公桌上有2台或以上的电脑(比如一个台式机,一个笔记本),那么有个问题一定在困扰着你。那就是两台电脑有各自的一套键鼠设备。来回切换使用两台电脑的时候要在两套键鼠设备之前切换,非常不方便。同时,两套设备还会占据办工作上很大的空间。 今天要分享一个神器帮你解决这个问题,那就是微软出品的Mouse without Borders。通过它,你可以利用一套键鼠设备在若干台(最多4台)电脑之前无缝切换。就好像是在两个连接在同一个电脑的两个显示器之间切换一样方便。 使用方法 下载并安装Mouse without Borders,需要连接的两台电脑上都要安装。 下载地址 在两台电脑上都启动程序。会看到如下的欢迎界面 在第一台电脑上点击NO,看到如下页面。记下这里的SECURITY CODE。 在第二台电脑上点击YES,输入之前记下的SECURITY CODE和主机名。点击LINK。 连接成功后会出现以下提示界面: 按需修改配置。配置界面如下。通常默认配置已经够用了。如果确有需要按需调整即可。 功能,特色 Mouse without Borders的主要特色有: 一套键鼠控制多台设备 各台设备间完全平等,可以使用任意一台主机的键鼠控制任意其他主机 各台主机间共享剪切板内的内容,随意复制粘贴(支持复制文件) 支持在主机间拖拽复制文件 可以截取任意一台设备上屏幕的内容(Ctrl+Shift+S进入截屏模式,鼠标拖拽选择截屏区域,在本地打开画图工具,Ctrl+V即可看到截图内容) 缺点 我的能想到的唯一缺点就是不支持跨平台,仅支持Windows操作系统。毕竟是Microsoft出品。。。 类似产品 Synergy 功能与Mouse without Borders类似。主要区别在于,与Mouse without Borders相比: 优点: 跨平台 支持Windows Linux Mac 缺点: 有服务器,客户端的概念。只能使用服务器的键鼠控制其他主机 不支持在主机间复制粘贴文件或拖拽复制文件(官方宣传支持该功能,但始终复制不成功) 不支持截取其它主机的屏幕 综上,如果你需要跨平台,那么没得选,只能Synergy。否则果断选择Mouse without Borders。
嗯,就是学习一下,读读源码。顺便把源码里的文档翻译了一下并添加了一些简单的注释。 本文对应的文件是src/createStore.js import isPlainObject from 'lodash/isPlainObject' import $$observable from 'symbol-observable' /** * ActionTypes里定义的是Redux保留的私有action。 * 对于任何未知的action,你必须返回store的当前状态。 * 如果传入的当前状态是undefined,你必须返回store的初始状态。 * 不要在应用代码中直接引用这些action。 */ export var ActionTypes = { INIT: '@@redux/INIT' } /** * createStore方法用于创建一个保存程序状态的store。 * 改变store中数据的唯一方法是调用store的`dispatch()`方法。 * * 你的应用中应该只有一个store。为了将程序状态中不同部分的变更逻辑 * 组合在一起,你可以通过`combineReducers`方法将多个reducer组合成一个reducer。 * * @param {Function} reducer 一个返回应用下一状态的函数,入参是程序的当前状态以及 * 要发送的action。 * * @param {any} [preloadedState] store的初始状态。你可以选择性的为store指定一个 * 初始状态。 * 如果你使用了`combineReducers`方法来生成最终的reducer。那么这个初始状态对象的 * 结构必须与调用`combineReducers`方法时传入的参数的结构保持对应关系。 * * @param {Function} enhancer store增强器。你可以选择性的传入一个增强函数来扩展 * store的功能,例如中间件,时间旅行,持久化等。Redux自带的唯一一个增强器是 * `applyMiddleware()`方法。 * * @returns {Store} 返回一个可以读取状态,发送action以及订阅变更通知的Redux store。 */ export default function createStore(reducer, preloadedState, enhancer) { // 如果只传入reducer和enhancer,则store的初始状态为undefined if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { enhancer = preloadedState preloadedState = undefined } // enhancer必须是一个函数 if (typeof enhancer ! ... Read More
原文地址 http://cryto.net/~joepie91/blog/2016/05/11/what-is-promise-try-and-why-does-it-matter/ 在#Node.js#频道里经常困扰大家的一个话题是Bluebird提供的Promise.try方法。大家并不清楚该方法的功能也不知道为何要使用它。同时,几乎所有的关于Promsie的指南中针对该方法错误的演示使得这种情况没有任何改善。 在本文中,我会尝试解释究竟什么是Promise.try以及为何你应该使用它。我假设你已经对Promise有所了解并且知道.then在Promise中的作用。 即使你在使用一个不同的Promsie实现(例如ES6 Promise),本文还是可以帮到你。文章末尾我会解释如何在非Bluebird环境中实现相同的功能。 究竟什么是Promise.try呢? 简单来说,除了不需要跟在一个前置Promise之后以外,Promise.try很像.then。这么说还是有一些含糊不清,所以让我们先看一个示例。 以下是一段典型的Promise使用场景: function getUsername(userId) { return database.users.get({id: userId}) .then(function(user) { return user.name; }); } 到目前为止,一切顺利。我们假设database.users.get会返回一个Promise,并且该Promise最终会返回一个带有name属性的对象。 以下是同样的代码,但是引入了Promise.try: var Promise = require("bluebird"); function getUsername(userId) { return Promise.try(function() { return database.users.get({id: userID}); }).then(function(user) { return user.name; }); } 可以看到,我们的调用链以Promise.try而不是database.users.get开始。像使用.then一样,我们执行Promise.try方法并传递给它一个直接返回database.users.get调用的函数。 这样做有什么意义呢? 以上的代码看起来似乎是多余的。但实际上它有以下几个优点: 更好的错误处理 同步代码中的异常不论出现在何处都会以rejection的形式向Promise链后端传递。 更好的兼容性 你可以始终使用你自己喜欢的Promise实现,而不用担心第三方代码在使用哪个。 更好的代码阅读体验 所有的代码在水平方向上将处于同一个缩进层级,这将使你阅读代码变得更容易。 接下来我会逐一介绍这些优点: 1. 更好的错误处理 Promise的一个被大力宣扬的优点就是用户可以用同一种方式同时处理同步异常和异步异常 —— 同步异常会被捕获并且会作为一个rejected Promise向后传递。但事实真的是这样吗?让我们看看以下这个上文示例的小变种: function getUsername(userId) { return database.users.get({id: userId}) .then(function(user) { return uesr. ... Read More
原文链接 https://medium.freecodecamp.com/finding-time-to-become-a-better-developer-eebc154881b2#.t1uuonhtf 没有时间做任何事。这就是你感受,不是吗?没有时间学习你觉得你需要学会以跟上潮流的知识。没有时间回过头去重构那些丑陋的代码。它至少能工作,何况截止日期马上就要到了。没有时间编写单元测试。没有时间为今后要维护你代码的伙计编写文档或注释。没有时间思考。没有时间呼吸。没时间! 好吧…如果你能花时间阅读本文,我保证你自己会为那些重要的事找到更多时间。 我曾经以为成为一名伟大程序员的唯一途径就拼命工作。我的健康,友谊,家庭都因此受到影响。理解以下5个关于时间管理的真相拯救了我。 1. 你不需要为了赶潮流而学习每一个新事物 你不需要 毫无疑问一个优秀的程序员应该保持不断的学习,但是你把学习的焦点放在哪儿能在很大程度上影响你需要花费的时间。 “老的事物已经死去,(终归老去的)新事物万岁!” 首先,不要被出现在那些每37秒就宣布一个新标准的博客上的头条所愚弄。这些新技术,新框架,新特性中的大多数永远都不会被认可与采纳,因此你根本不需要了解它们。那些真正能够脱颖而出的也会经历比博客圈和发明厂商宣传的长的多的时间才会被采用。公司投资于他们的技术栈 —— 和那些小创业公司不一样,他们不可能说变就变。所以,放松一下,你的职业生涯很安全。 把你的学习聚焦在三方面,以下面列出的顺序为优先级: 1. 基础 —— 当你有了非常扎实的基础知识之后,学习新技能会变得非常容易。举个例子,如果你对JavaScript有着深入的了解,你就可以飞速的掌握任何新的JavaScript框架。如果你深入学习了面向对象编程,你也能快速掌握任何新的面向对象语言。深入学习基础知识会极大的提高你的学习效率。始终把提高对基础知识的掌握放在第一位。 2. 你最常使用的技术栈的最新版本/特性 —— 存在一套你每天都会使用的技术栈。这些是可以帮你养活你及你家人的工具。当这些工具的新版本发布时,投入时间学习是很值得的。 3. 由市场领导者主导的流行技术 —— 如果一个颇具规模的公司,比如Google,Facebook或是Microsoft提出某项新技术并已经开始小有名气,这也值得你的关注。市面上曾经有许多JavaScript框架争夺人们的注意力,然后Angular和React出现了并将那些框架彻底消灭。我不是说今后不会有搅局者出现成为下一个焦点,但实际情况往往是杂牌技术只不过是一些噪音。 学习时间应该是你日程安排的一部分。每天抽出一点时间来学习。这不需要很长的时间,即使是每天花25分钟阅读和练习也可以快速积累。 2. 编写优秀的代码比编写糟糕的代码需要更少的时间,但感觉上并不是这样 时间是一个扁圆 你很可能喜欢开发完几个新功能后当你试着运行并且发现似乎可以正常工作时那一刻的感受。但那只是你时间投入的开始。在一个功能上投入的时间包括了后期调试的时间,重构花费的时间以及解决由于开发时的不良设计导致的其它问题的时间。当你开始以这种方式认识你的时间投入时,你会发现,从长远来看,更少的错误和更好的设计是值得投资的。 你可以做两件事来减少代码中的错误并实现更好的设计。 1. 使用测试驱动开发 首先编写测试,然后编写代码以使测试通过。这不仅会减少bug还会导致更好的设计,因为当你按照可测试的方式组织代码时,你最终会得到更小,更简单的,依赖更少的函数。 2. 使用迭代的设计方式 在你的代码能真正工作之前,不要花时间试图让你的代码变完美。你永远不可能在脑子里把它设计的完全正确。你必须敲击键盘来生成实现预期功能的代码。问题是程序员尝尝犯两个常见的错误:要么时花了太多时间思考而没有足够的时间动手,要么就是不去优化他们最初的方案。遵循最初由Kent Beck提出的口头禅:“make it work, make it right, make it fast” —— 按照话中的顺序。 3. 7x24的工作不会让你成为英雄,管理预期才会 下班到家,开始工作! 这一条几乎杀了我。我曾经同意并承诺过我老板或客户提出的任何疯狂的时间表。我害怕说“不”。我害怕让任何人失望。为了交付我可以做任何事。我曾经睡在办公桌下,有过多次长达40+小时的马拉松式的编程经历。 起初我是一颗耀眼的明星。别人对我大加赞赏,我感觉自己像是个英雄。但是我设置了一个不可能实现的预期。不可能长久的像那样工作。最终我开始疲惫不堪,生病并错过截止日期。我开始得到不可靠的名声。这是个坏消息。 最后我终于明白真正的英雄是那些持续可靠的人。他们说到做到。要成为那样的英雄的唯一途径就是管理预期。 你需要控制时间表以便总是可以按时交付高质量的工作。起初这会非常困难。这意味着必须说“不”并把需求打回。 在最开始,你的老板和客户不会被你的拒绝刺激到。但一旦你证明自己是值得信赖的,一切都将开始改变。 随着时间的推移,其它程序员会迟到,交付马虎的工作或是筋疲力竭变得不可靠。这时你就会成为团队中真正的英雄。事实上,学会这一点让我成为我的领域里最受欢迎的咨询顾问。由于狠抓预期管理,我在质量和时效性方面建立了良好的声誉。 4. 不是所有花在“改善”代码上的时间都会得到相同的回报 花费时间是一种投资。和所有投资一样,投资回报率是一个合理的期望。你的所得至少应该和投入一样多,希望是越多越好。 我们已经谈论过“make it work, make it right, make it fast”。这个是不错的口头禅但这里有一个陷阱:“right”并不意味着完美,“fast”也不是说越快越好。 ... Read More
最近在学习ES6 Generator特性时发现了koa这个基于Generator的Web框架,它可以让开发者以一种“同步的方式”编写包含各种异步请求的Web应用。下面是关于它的一段中文介绍: 由 Express 原班人马打造的 koa,致力于成为一个更小、更健壮、更富有表现力的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升常用错误处理效率。Koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。 从介绍中可以看出这又是一个小而美的框架。到GitHub项目页面上看了一下发现源码里只有4个JS文件,总代码量只有1571行(以2015年12月26日最新稳定版1.1.2为准)。于是决定把代码clone下来学习一下,本篇会先从整个框架的入口文件lib/application.js说起。 总体说明 lib/application.js文件export出的是一个构造函数,用来创建一个koa应用。一个koa应用最常用的方法有2个: - listen(port) 执行listen后会通过http.createServer启动一个服务器并监听指定端口 - use(middleware) 注册一个中间件,一个koa应用可以注册多个中间件, 处理请求时会按照中间件注册的顺序执行这些中间件。 更多详细信息可以参考GitHub文档页面。 代码注释 function Application() { if (!(this instanceof Application)) return new Application; this.env = process.env.NODE_ENV || 'development'; this.subdomainOffset = 2; this.middleware = []; this.proxy = false; this.context = Object.create(context); this.request = Object.create(request); this.response = Object.create(response); } 以上就是Application构造函数的定义,很简洁,主要做了以下几件事情: - 通过instanceof判断来支持不带new关键字的调用。 - 设置应用运行环境,会从环境变量NODE_ENV读取,默认值为development - 声明this. ... Read More