issue-blog icon indicating copy to clipboard operation
issue-blog copied to clipboard

技术积累和沉淀

Results 30 issue-blog issues
Sort by recently updated
recently updated
newest added

> `EventEmitter`是`node`中比较核心的模块,除此之外,`net.Server、fs.ReadStram、stream`也是`EventEmitter`的实例,可见`EventEmitter`的核心重要性了 ### 介绍 `node`中的事件模块是发布/订阅的一种模式,这个模块比前端中的大量DOM事件简单一些,不存在事件冒泡,也不存在`preventDefault()、stopPropagation() stopImmediatePropagation()`这些控制事件传递的方法。它包含了`emit,on,once,addListener`等方法。具体的用法可以移步[官网](https://nodejs.org/dist/latest-v8.x/docs/api/events.html) ### 源码解析 `node`中涉及`EventEmitter`的代码位于`lib/events.js`,其中的代码也很简单,主要是构造了一个`EventEmitter`对象,并且暴露了一些原型方法。源码比较简单,这里只解析一些自己觉得有必要记录的地方。 - `emit`原型方法 `emit`方法中做了一些参数的初始化以及容错处理,核心部分是根据所传参数个数不同而做的不同处理,代码如下: ```js switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: emitOne(handler, isFn, this,...

node
javascript

## express中的路由和应用 `express`中的路由还是很强大的,`express`中的路由实现主要有如下几种形式: ### 应用实例路由 直接上代码: ```js var express = require('express'); var app = express(); // get路由 app.get('/', function(req, res) { res.send('get'); }); //post路由 app.post('/', function (req, res) { res.send('post');...

node
express

最近在研究`experss`,在造过一个简单的[轮子](https://github.com/SunShinewyf/express-demo)之后,想通过研究一下它的源码来了解一下内部的实现原理,如有不对的地方希望得到大家的指正。 研究的`express`版本为`4.15.0`,应该算是比较新的版本了。 ### 文件结构及内容 ```js - lib/ - middleware/ - init.js - query.js - router/ - index.js - layer.js - route.js - application.js - express.js - request.js - response.js -...

node
express

继上次对`express`进行简单地了解和深入之后,又开始倒腾`koa`了。对于`koa`的印象是极好的,简洁而有表现力。和`express`相比它有几个比较明显的特征: - 比较新潮,`koa1`中使用了`generator`,拥抱`es6`语法,使用同步语法来避免`callback hell`的层层嵌套。在`koa2`中又拥抱了`es7`的`async-await`语法,语法表现形式更为简洁。 - 变得更轻量化,相比于`express`,`koa`抽离了原先内置的中间件,一些比较重要的中间件都使用单独的中间件插件,使得开发者可以根据自己的实际需要使用中间件,更加灵活。就比如给开发者建造了一个简单的地基,之后的装修设计都由开发者自己决定,精简灵活。 关于更多更详细的两者以及和`hapi`的比较,读者可以移步[这里](https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-koa-hapi) 在源码方面,`koa`变得更加轻量化,但是还是很有特点的。目录结构如下: ```js - lib/ - application.js - context.js - request.js - response.js ``` 从目录结构来看,只有四个文件,摒弃了`express`中的路由模块,显得简单而有表现力。四个文件中分别定义了四个对象,分别是`app`对象,`context`,`request`以及`response`。深入源码查看,你会发现更加简单,每个文件的代码行数也是很少,而且逻辑嵌套并不复杂。 ### 中间件原理 首先定义了一个构造函数,源码如下: ```js function Application() { if (!(this...

node
koa

继上一次的`koa`源码解读,今天来聊一下`koa-router`。 ### 文件结构及内容关联 从源码文件中可以看到,`koa-router`只有两个文件,`layer.js`和`router.js`,分别定义了`Router`和`Layer`两个对象。相对于`express`的内置路由,`koa-router`少了一个`route`对象,使得逻辑更加简单,下面通过一张图来解释`Router`和`Layer`对象之间的关系。 ![images](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/6.png) 正如上图显示,`Router`对象中有一个`stack`的成员属性,而`stack`又是一个由`Layer`组成的数组,这样就使两者关联起来了。两个对象之间的原型函数函数也列举出来了,比较直观和简单。 ### 运行流程 在我们的项目路由文件中引入`koa-router`的时候,如下: ```js const router = require('koa-router')() ``` 然后执行定义如下路由的时候: ```js router.get('/', async (ctx, next) => { await ctx.render('users/index',{ title:'用户中心' }) }) ``` 其实首先调用的是`router.js/routes`这个入口函数。下面为`routes`函数的源码:...

node
koa

> `egg-init`是`egg`的一个脚手架,用于快速生成一个`egg`项目或者插件 在剖析`egg-init`之前,先介绍一下脚手架的相关知识 ### 关于脚手架 脚手架主要是在项目启动过程中生成一些初始文件的,而且一旦生成了初始化文件之后,脚手架就没有用武之地了。但是在一个工程化体系过程中,脚手架的作用还是很大的: - 规范团队中的协作开发 - 快速生成配置文件,节省开发时间 - 降低框架的学习成本 脚手架一般运行在本地,并且有一些配置选项可以选用。 目前比较流行的脚手架就是`yeoman`,具体怎么使用可以移步[这里](http://yeoman.io/) ### 如何开发脚手架 - `npm bin` 需要在`package.json`中声明`bin`字段的命令 ```js "bin": { "init": "bin/init.js" }, ``` - 建立相应的`init.js`文件 ```js...

node
egg.js

> 前言:之前并没有接触过`chrome`扩展,第一次接触`chrome`插件也只是使用二维码生成器,然后是老大给了一篇[教程](https://github.com/diamont1001/blog/issues/12)之后开始尝试,然后觉得还是蛮好玩的,便尝试了一个[demo](https://github.com/SunShinewyf/chrome-extension),是对自己收藏的书签进行美化还有添加的一些操作 对于`chrome`开发入门的一些知识,直接看[教程](https://github.com/diamont1001/blog/issues/12)和[这里](http://www.cnblogs.com/guogangj/p/3235703.html)即可,这里不赘述。 下面记录一些开发过程中踩过的坑以及解决方案: - 在`manifest.json`文件中,对于图标的定义,仅仅定义一个`default-icon`并不能生效,还需要定义一个`icons`的值,例如: ```js "icons": { "48": "icon.png" }, ``` - `chrome.storage.sync undefined?` > 这是因为在`manifest.json`文件中没有声明如下定义: ```js "permissions": [ "storage" ], ``` - 对于获取书签数据,需要在`manifest.json`中定义`permissions`,否则会获取不到数据 ```js "permissions": [ "storage",...

Egret是一套HTML5游戏开发解决方案,旨在为h5提供更加方便的开发体验。总的来说`egret`的功能还是很强大的,最近接手的一个需求的时候使用了`egret`,使用完之后感觉很棒,把自己的一些经验积累下来。 `egret`的官方文档地址在[这里](http://developer.egret.com/cn/),API很详细。 既然是写使用总结,还是从最简单的安装到使用吧,虽然官方文档里面也写得很清楚(捂脸)。 ## 安装 安装地址移步[这里](https://egret.com/downloads/engine.html) * 按照自己的机器安装`Egret Engine`即可 * 安装完后打开会出现如下界面: ![images](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/10.png) 此时我的`egret`引擎有两个版本,如果你想安装新的版本,可以点击上面图片面板中的"安装其他版本",进行下载,然后将解压之后的安装包拖进安装面板即可。 还要说的一点就是建议安装一个开发`egret`的编辑器`egret wing`,安装方式如下: 点击上面图片面板中的左侧边栏的“工具”栏,就会出现对应的一些工具: ![images](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/11.png) 找到相对应的这个工具,并点击`下载`即可 ## 新建项目 打开安装的`egret wing`,并且点击如下位置或者直接到“文件->新建项目"中进行建立新的项目: ![images](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/12.png) 此时会弹出一个项目类型的面板,根据你的需要选择一种项目类型就行。这里我选择的是`Egret Eui`项目,然后会弹出如下面板: ![images](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/13.png) 选择你所需要的库并填写相应的项目目录以及项目名称就大功告成了 ## 运行 你可以直接在`egret...

> 异步在前端中的发展历史不是很长,但是发展的速度还是很快的 ### 什么是异步 所谓异步,简单点说就是在做一件事情的过程中中断去做另外一件事情。js是单线程的,当然也有异步的概念。异步和同步的区别用图示表示如下: ![输入图片说明](https://raw.githubusercontent.com/SunShinewyf/issue-blog/master/assets/technical/1.png) 由图示可以得出,同步过程时:业务二必须等待业务一的请求结果返回之后才可以开始,而异步过程中,在业务一的请求过程中,当前线程可以先去处理业务二,免去了等待过程中的时间浪费。 ### 为什么要异步 为什么要引入异步的,异步有下面几点优点: - cpu利用率高 - 用户体验更好 - 性能更高 从上面图示可以看出,在异步过程中,没有等待数据返回的过程,在请求数据的时候,当前线程又去处理其他业务了,这样就提高了cpu的利用率,cpu的性能必定也会提升。其次,在之前的网站中,我们时常要处理ajax请求,一旦采用同步思路,那么在请求数据返回之前,网页都是一片空白而得不到相应,那样会给用户一种相应很慢的感觉,导致用户体验很差。而异步就使得页面在请求数据的空隙也可以渲染页面,大大提升了用户体验。 ### 异步的发展历程 ####```callback```时代 回调函数是异步发展的起源,最初源自```ajax```,对于下面的代码,相信每一个FEer都不会感到陌生: ```javascript $.ajax('url',function () { //do something }) ``` 但是这样的请求一旦嵌套过多,就会出现下面的```callbacks...

redux虽然强大,但是它的源码确实很简单 --- #### `createStore` createStore返回的是一个对象,并且这个对象有如下成员函数```dispatch,subscribe,getState,replaceReducer```和```observable``` 下面看它的核心源码(已经去掉一些对参数的判断): ```javascript if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { enhancer = preloadedState preloadedState = undefined } if (typeof enhancer !== 'undefined')...