分类目录归档:技术

JavaScript 异步流程控制的知识点整理

在写信息管理系统的时候,经常需要等待前面的任务执行完,比如最常见的Ajax请求后做弹窗提示,又或者是多个Ajax需要并行/串行执行操作等。

因为JS是单线程语言,所以在整个执行环境都依靠EventLoop。因此,实现异步除了最基本的Callback回调函数,社区还开发了Promise、Async/Await等语法糖或者库,我写一篇文章整理一下工作以来接触到的异步知识

Callback 回调函数

异步控制接触最早的,其实就是这个Callback回调函数,代码示例如下

// JQuery的Ajax请求
$.ajax({
   url: '/api/system/login',
   params: {},
   success: () ={
      console.log('在异步Ajax请求成功之后,会调用到此回调函数');
   }
});

// setTimeout/setInterval绑定回调函数
setTimeout(()={
    console.log('两秒之后会调用到此函数');
},2000)

// Node.js 经常的回调函数以及传参
var fs = require('fs');

fs.readFile('test.txt', 'utf-8', function(err, data) {
    // 这里同样绑定了回调函数,Node.js设计一般第一个参数是err,第二个参数是data数据等
    if(err) 

Redux数据流框架介绍,构建易维护的单向数据流

React本身是一个View层,尽管借助prop属性和事件,能够完成父子组件之间的通信,但是在一个逻辑复杂的系统里,往往DOM的层次很深,如果每一层都传递一遍prop,开发效率就会有所下降。

这个时候,我们需要有一个专门管理数据流的框架来处理——Redux,通过Store/Dispatch/Reducers等概念,将整个数据流进行抽象。除此之外,还能加一些中间件(middleware)来进行拦截操作。下面我整理一下我使用Redux以来的一些知识点

1, 安装Redux依赖

基础框架可以使用我的开源仓库https://github.com/tun100/webpack-configure-react,并且在package.json里添加以下依赖,并且执行命令cnpm i -S -D

    "react-redux": "^5.0.5",
    "redux": "^3.7.2",
    "redux-saga": "^0.15.6",

2,最简单的Redux配置

首先,在import顶部增加以下代码

import React, { useEffect, useState, useContext, PureComponent, Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider, connect } from "react-redux";
import { 

使用Babel的AST功能,来智能分析处理源码

在重构时,往往会遇到一些不合理的代码需要被批量替换。这种需求一般的全文替换是可以的,但是如果要根据文件名、变量名动态的进行智能替换,而且被替换的代码块格式不一,这时还有什么方式?正则是一个办法,但是还有没有别的方法可以尝试呢?

有的!之前在重构某些项目时,有许多属性需要批量替换,但是我希望能加入一些逻辑判断、和一些其他变量的状态获取。在查询许多资料之后,除了正则+脚本,还有Babel能帮我解决这个问题

Babel

我们一般前端开发是用Babel来转换新语法,然而它的API也能让你来自定义转换源码。这个API就是将你的源码转换成AST(Abstract Syntax Tree)抽象语法树。能实现AST转换的其实不止Babel一家,在Babel之前还有Esprima等。只不过我们大部分用的都是Babel,为了和.babelrc语法一致,所以我更推荐使用Babel来进行AST转换

AST(抽象语法树)

维基百科:在计算机科学中,抽象语法树(AST),或简称语法树,是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示源代码中出现的一个构造。

例如:Program -[Code1 ,Code2],同时Code1又包含
VariableDeclaration(变量定义)、CallExpression(函数定义)等,在函数内又有许多语法在其中。这么一看,是不是很像一颗树呢?有树层次、节点关系等^_^。然后实践的过程中,只要我们增减其中的节点,或者是修改节点的属性值,再将AST转换成源码,这样就可以很轻松的达到“智能转换代码”的功能了!

学习资料

官方手册:
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/README.md

AST Explorer(在线解析语法AST):https://astexplorer.net/

维基百科定义:https://en.wikipedia.org/wiki/Abstract_syntax_tree

具体实践

只是给出几个定义感觉不直观,让我们直接上手AST吧!相信AST能让你今后的重构或者代码调整,能够如虎添翼,这并不是奇巧淫技,而是真正提升你效率的一个利器!下面列出一个Github仓库,这是我实际用AST进行转换的例子:

Github仓库:
https://github.com/tun100/ReplaceContentByBabelAST

实际需求:

替换前文件
替换后文件

我们现在需要拿到{form.getFieldDecorator(‘myname’, {})}的“myname”字符串,这是定义form的prop值的。然后对Form.Item的label需要改为传递<ErrorTooltip>

一般正则是可以使用,但是AST也可以帮助你实现这个功能,让我们打开index.js这个文件

index.js文件概览

在进行AST处理时,我们会通过core.parse得到一颗树。那么我们怎么去遍历,去拿到这个值呢?这时候会用到traverse这个函数,通过这个函数,它可以帮你遍历所有的节点,如果你判断当前的tree node符合你的条件,那么就立刻进行处理,如下图:

具体解析转换代码

在语法树中,每个节点都有自己的定义,比如:节点是什么语法,带有什么属性,自身是什么值,在自己语法下还有没有更深层次的子树存在。那么这些节点具体有哪些属性,我应该怎么知道呢?

其实有一个很快捷的方式,就是把你的代码拷贝到 https://astexplorer.net (如果不放心可以clone它的仓库,在本地运行,不过我检查过不会有隐私问题),然后在菜单顶部选择babylon7,这样右侧就会有你想要的各个节点的属性和之间的关系

AST-Explorer具体使用

手动配置webpack 4.x,定义属于自己的脚手架

概述

webpack作为一个构建工具是非常优秀的,提供了多页面、Plugin、Loader等功能,而且还有基于webpack的零配置工具(如create-react-app)等。在webpack应用如此广泛的情况下,我觉得有必要深入了解webpack并从零开始配置,因为至少出了问题能很快的找到异常配置并快速修改好。之前搭建webpack也好多次了,但是没有进行总结。这次决定从头开始搭建,然后边操作边记录

之前还用过Parcel等新秀解决方案,它讲究的是零配置,用过在一些小项目上,但貌似还不太稳定,经常会出编译错误,所以又跑回了webpack的怀抱^_^

测试环境

Node.js: 8.14.0

Npm: 6.4.1

已搭建好环境的仓库

为了方便随时Clone出webpack编译环境,我把最终环境部署在Github仓库上了,
地址是:https://github.com/tun100/webpack-basic-frame

依赖初始化

npm init -y

然后将下面的依赖信息添加到package.json(因为不同依赖版本的差异,容易导致bug,如果使用我的这个依赖,我确信肯定能构建环境成功^_^),在添加成功之后执行npm i -S && npm i -D

   "scripts": {
     "dev": "npx webpack-dev-server --config ./webpack.dev.config.js --progress --profile --colors --watch --mode development",
     "dist": "npx webpack --config 

【React快速学习一】基础JSX语法和生命周期

学习React也有近两年多的时间,因为一些知识点用久了容易忘记,决定找空闲时间整理下自己理解的React知识文章,顺便做一下总结!😀

什么是React

React不同于以往的JQuery+BootStrap,它是一个简单的View层框架,搭配上周边生态(Redux/Mobx/ReactRouter等),就能构建起各种逻辑复杂的系统。

我所理解的React框架具备以下特点:

1.,使用JSX语法

借助该语法,可以在JavaScript文件里混编类似HTML的代码,不仅支持原生H5标签,还可以支持用户自定义的React组件,该语法风格如下:

let Clock = () =<divthis is clock</div// 此处渲染了一个React组件
ReactDOM.render(
    <Clock/,
    document.querySelector('#root')
);

2,采用VirtualDOM优化渲染性能

浏览器内核有JS引擎和渲染引擎,每当JS手工去操作DOM树的时候,往往会引起Repaint或者Reflow,这个操作会比较耗时,从而导致页面性能不佳

于是,开源社区想出了一个VirtualDOM的解决方案。使用JavaScript来虚拟定义一个DOM树,并且更新之前会对虚拟DOM节点进行比较,React会根据比较结果,只会部分更新所需的DOM节点,减少了不必要的渲染工作

不仅React,还有Vue等框架也采用了VirtualDOM diff算法,思想都是大同小异,下面是相关代码说明

// 在React里,VirtualDOM定义的元素格式如下
{
  type: "div",
  props: null,
  children: [{type: "text", props: {textContent: "Hello"}}]

使用SSH密钥,更安全快速的免密登陆到Linux服务器

为什么用密钥替代传统的密码

因为密码虽然可以设置复杂一些,但终究还是不方便管理,需要管理员手动输入一遍又一遍。还有密码的安全性也是一个令人担忧的地方,如果要在公网暴露公网IP,我不太敢让服务器提供密码鉴权服务(虽然也有failban,但是依旧不信任),毕竟有那么多攻击四处寻找目标,一切要以安全为核心

如果使用密钥,上面的担忧都可以消除了!因为密钥首先加密长度不短,需要暴力破解没个几年日夜不停的话,被攻击成功的可能性还是比较小的。其次,密钥在手,可以免密登陆,在经常登陆的场景下非常方便,甚至一个私钥我可以登陆所有服务器,而不需要任何密码输入,可以说非常方便

密钥创建

如果是windows,请先安装git-bash,它会给你许多Linux下的工具(不是所有)。如果是Linux,不需要做任何操作,一般都有必备的软件工具

在自己的主目录下创建.ssh主目录(win是C:\users\${user},Linux是~):

ssh-keygen -b 4048

第一次询问文件名称,如果没有即回车,有的话将会输出到当前文件夹下。后面的询问都直接回车即可

正常情况下,应该是生成了test.pub和test这两个文件(我拿test作为示例),test.pub是公钥,是传送给目标Linux服务器的,test是私钥,是用来后续登陆使用的

拷贝公钥到目标服务器

ssh-copy-id -i ./test.pub root@${ssh_ip} -p ${ssh_port}

拷贝最后会要求输入密码,输入之后没有错误即完成了

使用私钥进行SSH登陆

ssh -i ./test root@{ssh_ip} -p ${ssh_port}

更安全的SSH登陆配置

只是密钥登陆还不是最佳实践,更安全的配置请参考我之前的写的文章…

Linux服务器安全建议以及相关配置

能处处都特别理想,我按照我思考的最理想的配置来描述,可能有不对的地方,请多多包涵和指出!

1,永远不要关闭iptables

我以前为了方便开发调试,经常执行iptables -F清空所有规则,但是后面深入了解网络安全,发现这样会导致服务器处于无保护状态。至少要确保每个端口开放都是明确的,否则会很不安全

2,SSH只允许密钥登陆,禁止密码登陆和Root远程登陆权限,修改22端口

如果密码不复杂,那么允许密码登陆也会导致服务器不安全。我推荐使用密钥进行登陆,过几天有空写一些专门的SSH密钥配置流程。

接下来编辑/etc/ssh/sshd_config,修改一些参数:

修改22端口,和禁止Root登陆
禁止密码登陆

3,不能随意给Root权限,在chmod设置权限的时候谨慎给与其他用户组rwx

root账号应该是顶级用户使用的,具体分配给成员各自的账号,在/var/log/下各种操作都可以一目了然。如果都是root权限,那么在出问题的时候很难查出是谁操作的(随意删除操作日志、.bash_history等)。还有,Linux的权限系统限定了owner,group,other users,不能随意的设置文件777权限,这可能会导致部分用户可以读取执行隐私文件…

Linux系统配置lrzsz,配合XShell提升使用体验

在传统的Linux文件上传下载,一般是需要用到SFTP或者Rsync、FTP等协议,然而有一个更快捷更方便的方法,可以让你在上传下载时效率提升N倍

这里用CentOS7作为示例,首先安装相关的软件包:

yum -y install lrzsz

然后,在windows打开xshell,登陆目标服务器的SSH控制台,你可以尝试拖拽一个文件到控制台下,如图:

是不是很方便,它传送的目标地址就是你当前控制台的位置

那么怎么传送当前控制台下的某个文件呢?很简单,输入 sz ${YOUR_TARGET_FILE}即可:

sz mytarget.tar

选择好目标即可进行传送

这个方法真的非常提升效率,减少了误操作,强烈推荐


Linux的LANG语言编码配置

语言编码配置,是非常重要的,如果设置了不恰当的语言编码(比如英文或者GBK),同时你又尝试运行基于UTF-8的Java应用程序,那么乱码概率可是相当的大的!

临时设置:

export LANG=en.US

永久设置

vi /etc/locale.conf ,使目标编码生效即可(去除前面的#号)…

CentOS7在执行groupinstall的时候报错

因为在一开始选择了minmal install,许多依赖包没有安装,输入下面命令执行就可以了

yum groupinstall “Office Suite and Productivity” –setopt=group_package_types=mandatory,default,optional

然后,再执行yum group list,可以看到有许多套件,安装即可(记得组建名要大小写一致,用引号标注):