百度
360搜索
搜狗搜索

阮一峰js教程,来自一位react新手的react入门须知详细介绍

本文目录一览: JS实现HTTP请求头-Basic Authorization

HTTP协议中的 Authorization 请求消息头含有服务器用于验证用户代理身份的凭证,通常会在服务器返回 401 Unauthorized 状态码以及 WWW-Authenticate 消息头之后在后续请求中发送此消息头。
格式是Basic字符串+空格+ 用户名:密码 的Base64编码。 将凭证

部分进行Base64编码,然后再拼接字符串'Basic ',就可以生成基础验证方案。 因为DOMString 是16位编码的字符串,如果有字符超出了8位ASCII编码的字符范围时,在大多数的浏览器中对Unicode字符串调用 window.btoa将会造成一个 Character Out Of Range 的异常。 所以下列方法将UTF-16的 DOMStrin 转码为UTF-8的字符数组然后再编码。

将UTF-16的 DOMString 转码成UTF-8的字符串进行base64编码

使用 eoLinker 发送Basic Auth,输入用户名scar 密码123456

PS: eoLinker是一个很好用的接口管理网站,前端测试很方便

在JS Bin运行后,发现和eoLinker结果一致,成功!!

Authorization Authentication Javascript base64 Base64的编码与解码 Base64笔记-阮一峰老师 btoa方法

Nodejs 使用node-rsa 加密数据

RSA算法原理 阮一峰

1、在node.js中使用rsa算法。首先需要是使用node-rsa包

2、实现加密/解密

客户端需要使用一个jsencrypt.min.js 包利用公钥对数据进行加密

以上运行时可以会出现如下错误

出现如上错误的时候,是服务端的加密方法和jsencrypt的加密方式不一致导致的。jsencrypt加密方式是pkcs1,node-rsa 默认的加密方式是pkcs1_oaep。解决办法如下:

在D3.js中如何实现动态进度条

D3是一个被数据驱动的文档。这篇文章主要介绍了基于 D3.js 绘制动态进度条的方法,需要的朋友可以参考下D3 是什么D3 的全称是(Data-Driven Documents),顾名思义可以知道是一个被数据驱动的文档。听名字有点抽象,说简单一点,其实就是一个 JavaScript 的函数库,使用它主要是用来做数据可视化的。如果你不知道什么是 JavaScript ,请先学习一下 JavaScript,推荐阮一峰老师的教程。JavaScript 文件的后缀名通常为 .js,故 D3 也常使用 D3.js 称呼。D3 提供了各种简单易用的函数,大大简化了 JavaScript 操作数据的难度。由于它本质上是 JavaScript ,所以用 JavaScript 也是可以实现所有功能的,但它能大大减小你的工作量,尤其是在数据可视化方面,D3 已经将生成可视化的复杂步骤精简到了几个简单的函数,你只需要输入几个简单的数据,就能够转换为各种绚丽的图形。有过 JavaScript 基础的朋友一定很容易理解它。在网站页面加载以及表单提交时,常使用进度条表达加载过程来优化用户体验,常见的进度条有矩形进度条和圆形进度条,如下图所示: 我们经常使用svg或canvas来实现动态图形的绘制,但绘制过程相对较繁琐。对于直观漂亮的进度条,社区也有提供成熟的方案例如highcharts/ECharts等等,但基于配置的开发方式终究无法实现100%的自定义绘制。本文将带你使用D3.js从零一步一步实现动态进度条,并分享代码逻辑原理。基础要求了解svg如何绘制基础图形了解D3.js v4版本了解如何使用D3.js (v4)绘制svg的基础图形绘制圆形进度条对于一个圆形进度条,我们先对其进行任务拆分:绘制嵌套圆弧圆心处的实时数据展示展现动画美化1.绘制嵌套圆弧对于圆形,svg提供现成的 circle 标签供使用,但是其劣势在于,对于圆形进度条使用 circle 可以满足,但对图形进一步扩展时比如绘制半圆, circle 的处理就棘手了。D3.js提供 arc 相关API对圆形的绘制方法进行了封装:上述代码实现了对两个嵌套圆的绘制逻辑, d3.arc() 返回一个圆弧构造函数,并通过链式调用设置内圆与外圆的半径大小,起始角度与结束角度。执行 arc() 构造函数即可获得用于绑定在

上的路径数据。完整代码如下:上述代码实现了2个步骤:1.生成将0度作为起点的圆弧构造器 arcGenerator2.设置 transform 图形偏移量,令图形在画布中央目前画布上还没有任何元素,接下来我们实际图形的绘制。我们对画布 picture 添加

元素,依据 endAngle() 特性,使用 datum() 方法将 {endAngle:Math.PI} 也就是终点角度 2π 绑定到

元素上,并将圆弧构造器赋值给 path 路径 d 。这样就生成了指定背景颜色的圆弧,实际图形如下:第一个圆弧画好了,那么依据svg的层级关系 z-index ,所谓的进度条其实就是覆盖在第一层圆弧之上的第二层圆弧。同理可得:代码运行后可得: 2.圆心处的实时数据展示第一部分我们已经实现了基于两个 path 的嵌套圆。第二部分我们来实现圆心处的实时数据展示。 在进度条进行加载时,我们在圆心处添加数据来表达当前的加载进度,使用

标签做展示即可:暂时将数据设置为12,并设置水平居中和垂直居中,效果如下图: 3.展现动画通过1,2两部分内容我们已经知道了:绘制进度条的实质是改变上层弧的角度当弧度是 2π 时为整圆,当弧度是 π 时为半圆圆形中的数据即为当前弧度相对 2π 的百分比综上我们只要改变弧度值和数值同时设定改变过程所需时长即可实现所谓"动画"。在ECharts提供的官方实例中,通过 setInterval 来实现每隔固定一段时间进行数据更新,其实在D3.js中同样提供了类似方法来实现类似 setInterval 的功能:对这段代码进行拆解:d3.interval() 方法提供了 setInterval() 的功能selection.transition.duration() 设置了当前DOM属性过渡变化为指定DOM属性的过程所需时间,毫秒为单位transation.attrTween 为插值功能API,那么何谓插值?概括来说,在给定的离散数据中补插函数,可以使这条连续函数通过全部数据点。举个例子,给定一个p,想实现其背景颜色的从左边红(red)到右边绿(green)的线性渐变,每一区域的色值该如何计算呢?只需:compute 即为插值函数,参数范围为[0,1],只要你输入该范围内的数字,那么 compute 函数将返回对应的颜色值。这样的插值有什么用呢?可看下图: 假设上图的p长度width为100,那么将[0,100]依比例关系转化为[0,10]的范围数据并输入 compute 函数中,即可得到某一区域对应的颜色。当然,对于线性面积的处理我们不应该使用离散数据作为输入和输出,所以D3.js提供更方便的线性渐变API d3.linear 等,这里就不展开描述了。言归正传,代码 d3.interpolate(d.endAngle,Math.random() * Math.PI * 2); 实现了如下插值范围:["当前角度值","随机角度值"] //表达区间而非数组而后返回一个参数为 t 的函数,那么该函数的作用是什么呢?t 参数与 d 类似,是D3.js内部实现的插值,其范围为[0,1]。 t 参数根据设置的 duration() 时长自动计算在[0,1]内合适的插值数量,并返回插值结果,实现线性平稳的过渡动画效果。完成滚动条的动画加载效果,我们接下来写圆心实时数据的变化逻辑,只要实现简单的赋值即可,完整代码如下:最终效果如下: 4.美化1,2,3部分我们实现了最基本的进度条样式和功能,但样式看起来还是很单调的,我们接下来我们对进度条进行线性渐变处理。我们使用D3.js提供的线性插值API:colorLinear 同样是一个插值函数,我们输入[0,100]区间中的数值,就会返回对应["#EEE685","#EE3B3B"]区间内的颜色值。比如当进度条显示进度为"80%"时:实现了颜色取值后,我们只需在进度条变化时,将原有颜色改变即可:styleTween 与 attrTween 类似,是实现改变样式的插值函数。采用链式调用的形式同时对进度条数值和颜色的设置即可。最终实现的效果如下: 综上我们实现了在不同数值下颜色变化的圆形进度条,可常用于告警,提醒等业务场景。绘制矩形进度条矩形进度条相比圆形进度条简单了很多,同样基于插值原理,平滑改变矩形的长度即可。直接上代码:实现的效果如下: 总结基于D3.js绘制进度条的关键点在于插值,从而正确地使图形平滑过渡。如果一定要使用svg或纯css实现矩形和圆形的进度条当然也是可行的,但对于路径和动画的处理,以及css的书写要求都复杂了不少。我们观察到使用D3.js绘制上述两种进度条的逻辑代码几乎完全使用js实现,同时代码量可以控制在20行左右并可封装复用,已经非常精炼了,在自定义图表开发上非常有优势。对于进度条的衍生版仪表盘图表,相比基础进度条增加了刻度描述和指针计算,但万变不离其宗,只要掌握插值原理和使用,处理类似图表都将得心应手。上面是我整理给大家的,希望今后会对大家有帮助。相关文章:基于express中路由规则及获取请求参数的方法js提取中文拼音首字母的封装工具类_javascript技巧详解vuex的简单使用

js文件上传中遇到的知识点

在前端开发中,我们经常遇到上传文件的需求,以前都是用到时再找资料,但总是感觉对这块不熟,最近翻资料学习了一下,记录一下。

本文中涉及的知识点有:FileList对象,Blob对象,File对象,URL对象、FormData对象等。

本文参考 网道 ,总结而来。另外,强烈推荐网道,可以去 网道的官方 看看,是阮一峰大神发起的项目,提供互联网开发文档,文档非常全面易懂。

FileList对象,是一个像数组的对象,拥有length属性和item()方法,同时,它的每一项都是File对象。

input 标签,将type设为file,之后得到的files属性就是一个FileList对象。

blob 对象表示1个二进制文件的数据内容。blob对象和arraybuffer区别是,blob对象用于操作二进制文件,arraybuffer用于操作内存。

blob 对象拥有2个属性和1个方法,分别是size(单位是字节)、type属性和slice()方法。

File 对象是一种特殊的Blob 对象。它在继承了size、type属性外,还同时有name、lastModified、lastModifiedDate等几个属性。

FileList 对象中的每一项都是File 对象。

拿到File 对象之后就要进行操作,下面是操作。

URL.createObjectURL(file) 允许为File 对象创建一个临时链接,

FileReader 对象的属性和方法比较多,属性中比较重要的是result,方法中比较重要的是

FileReader 对象的所有属性和方法可以参考 这里 ,这里就不再列出来了。

在早期的互联网时候,提交数据都是用表单。表单提交数据有些缺陷,例如无法校验表单数据,会刷新整个页面等。随着Ajax的兴起,页面表单提交数据慢慢退出历史舞台,但有时上传文件时我们偶尔会用到表单提交数据。

在调用构造函数new FormData(form)构造formdata对象时需要传入form节点,如果不传入,则默认构建空表单。如果传入,则按照key=value的时候构建表单。

可以看看效果图

FormData 对象主要的方法有:

cavas压缩图片其实很简单,无非就是几个步骤:
1、选择图片,判断图片是否大于2M(用File对象的size进行判断,size的单位是字节);
2、用FileReader对象读取文件成base64,
3、然后创建Image对象,赋值src属性,在Image对象加载完成的回调里创建cavas并绘制图片(根据图片是否大于2M动态调整画布大小);
4、将cavas转成blob,拼在formdata中用ajax上传。

这篇文章到这里也就结束了,这篇文章包含了一些浏览器中提供的对象,可以看到都是很简单的内容。

如何学习vuejs

最近VueJs确实火了一把,自从Vue2.0发布后,Vue就成了前端领域的热门话题,github也突破了三万的star,那么对于新手来说,如何高效快速的学习Vue2.0呢。既然大家会看这篇文章,那么肯定是vue的学习者了,或是遇到的瓶颈,或者刚刚开始学,不知道如何快速起步,本篇文章将带领大家在最短的时间内构件一个学习Vue的学习路线Vuejs的作者尤雨溪尤大也写过一篇关于新手学习vue路径的文章新手向:Vue 2.0 的建议学习顺序百度vuejs搜索的是vue1的文档,推荐大家直接上2.0,毕竟1和2还是有区别的。vue2.0文档地址Vue2.0Vue基础对于没有接触过es6和webpack的童鞋来说,不建议直接用官方的脚手架vue-cli构件项目。先按文档顺序最少学习完组件那一章。直接在html文件中引入vue.js开始学习,了解vue的基础指令和语法。vue的生命周期很重要,了解这点以后可以免去很多问题。学完这些可以做一些练手的小项目,比如万年不变的todolist。。。现在可以开始学习使用vue-cli构件项目了,学习组件化之前,推荐先看一下es6关于模块的介绍。阮一峰《ECMAScript6》 Module光会这些还是不够的,还得会一些npm基础,知道如何用git-bash来安装依赖,会一些常用的命令。这方面的知识可以参阅npm入门文档看完这些就可以试着将之前的写的demo用搭建的vue-cli来实现。附上我写的一个入门小demovue-demo-search多看看组件那里,看看如何在vue-cli中怎么实现组件化,说白了,vue玩的就是组件。到这里vue基础篇就结束了。你还可以有条件的参阅剩下的官方文档里面的进阶篇,如果时间有限,就直接进入vue-router Vue-router和之前一样,推荐直接用html+js过一遍文档对路由导航钩子得好好看一看。看完文档就可以上手vue-cli,一般新手在这几天都会死活跑不出来。偷笑最直接的方法就是去github上搜一些关于vue-router2.0的demo,看如何构件路由,如何构件项目目录。我这里有一个传送门如果能跑出来,就可以做一些小项目了,比如写一个知乎日报啊偷笑,这些demo在github上很多。可以结合一些组件库写demo,这样可以更加了解组件化。比如饿了么团队的Element、mint-ui Vuex什么是vuex?Vuex 是一个专门为 Vue.js 应用设计的 状态管理模型 + 库。它为应用内的所有组件提供集中式存储服务,其中的规则确保状态只能按预期方式变更。说白了就是控制应用的一些全局状态。状态改变了,对应的视图也会改变。在学习Vuex时,会有一些ES6特性,当遇到这些时,最好不要一带而过,去好好看一看这些es6特性。比如在学习Action时可以看看ES6新增的Promise和参数解构。实践的方法一样是先看别人别人写的代码,比如官方的购物车实例的应用结构。把之前写的demo优化一下,有些地方可以用用vuex。vuex主要是用来对不同组件间进行通信,它构建了一个Vue实例的全局数据与方法,这些数据与方法可以在该Vue实例的所有组件中getter与setter。

学前端有什么书推荐

一、《web前端开发最佳实践》
这本书是前端开发领域的经典之作,是一本扎实前端基本功,规范我们前端代码的实践性书籍。本书主要讲解了HTML、CSS、JavaScript以及移动端开发的最佳实践方案,能对缺乏良好知道的开发者产生很大的帮助。通过阅读本书我们可以掌握如何编写高可读性、高维护性、高性能的HTML、CSS以及JavaScript。
二、《CSS那些事儿》
《CSS那些事儿是2009年电子工业出版社出版的图书,作者是林小志。该书通过对CSS技巧实例进行讲解,深入地分析了CSS相关知识。
通过页面中的文字、图片、表格、表单等常见元素的处理及各种页面布局方式的使用,使读者能深入了解如何在页面中更好地运用CSS布局。尤其是在页面布局的部分中,全面分析了多重布局方式,着重分解了两列等高和三列等高的几种方式,并相应说明了等高布局的优缺点。
三、《CSS权威指南》
内容介绍:《CSS权威指南》通过诸多示例,详细讲解了如何做到仅在一处建立样式表就能创建或修改整个网站的外观,以及如何得到html力不能及的更丰富的表现效果。同时展示了如何遵循css最新规范(css2和css2.1)将层叠样式表的方方面面应用于实践。
四、《JavaScript 标准参考教程》阮一峰
内容介绍:阮一峰 本书全面介绍 JavaScript 核心语法,从最简单的开始讲起,循序渐进、由浅入深,力求清晰易懂。所有章节都带有大量的代码实例,便于理解和模仿,可以用到实际项目中,即学即用。 本书适合初学者当作JavaScript语言的入门教程,也适合当作日常使用的参考手册。
五、JavaScript高级程序设计第三版
内容介绍:《全书从JavaScript 语言实现的各个组成部分——语言核心、DOM、BOM、事件模型讲起,深入浅出地探讨了面向对象编程、Ajax 与Comet 服务器端通信,HTML5 表单、媒体、Canvas(包括WebGL)及Web Workers、地理定位、跨文档传递消息、客户端存储(包括IndexedDB)等新API,还介绍了离线应用和与维护、性能、部署相关的最佳开发实践。
六、锋利的jquery
内容介绍:《锋利的jQuery(第2版)》循序渐进地对jQuery的各种函数和方法调用进行了介绍,读者可以系统地掌握jQuery的选择器、DOM操作、事件和动画、AJAX应用、插件、jQuery Mobile、jQuery各个版本变化、jQuery性能优化和技巧等知识点,并结合每个章节后面的案例演示进行练习,达到掌握核心知识点的目的。
七、HTTP权威指南
内容介绍:《HTTP权威指南》由古尔利所著,《HTTP权威指南》详细解释了如何用HTTP来开发基于Web的应用程序,核心的[因特网协议,如何与架构构建块交互,如何正确实现因特网客户和服务器等。
《HTTP权威指南》的中心内容是HTTP,本质是理解Web的工作原理,以及如何将这些知识应用到Web编程和管理之中,主要涵盖HTTP的技术运作方式、产生动机、性能和目标以及一些相关技术问题。 《HTTP权威指南》适合所有想了解HTTP和Web底层结构的人阅读。
八、高性能网站建设指南
内容介绍:《高性能网站建设指南》结合Web2.0以来Web开发领域的最新形势和特点,介绍了网站性能问题的现状、产生的原因,以及改善或解决性能问题的原则、技术技巧和最佳实践。重点关注网页的行为特征,阐释优化Ajax、CSS、JavaScript、Flash和图片处理等要素的技术,全面涵盖浏览器端性能问题的方方面面。

阅读更多 >>>  linux命令行中文乱码怎么解决

js 如何同时判断 某个变量不是 undefined 也不是 null也不是 空啊

if(data){
console.log(1);
}else{
console.log(2);
}
只要 data 的值为 null undefined NaN empty string ("") 0 false
都会输出 2;
可以参考网页链接 ,
如果 变量 != null 结果为true,那么这个变量肯定不是undefined或者null
if (typeof(str) == "undefined")
{
alert("undefined");
}
if(str==null){
alert("null");
}
if(str==“”){
alert("空");
}
目前,null和undefined基本是同义的,只有一些细微的差别。undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。null表示"没有对象",即该处不应该有值。
本段摘取自阮一峰的日志 http://web.zhaicool.net/136.html

怎样用JS实现异步转同步

你可以使用回调函数,promise等实现异步转同步
ajax中就有设置是同步或异步
源起
小飞是一名刚入行前端不久的新人,因为进到了某个大公司,俨然成为了学弟学妹眼中'大神',大家遇到js问题都喜欢问他,这不,此时他的qq弹出了这样一条消息
"hi,大神在吗?我有个问题想问,现在我们的代码里面有这样的东西,可是得不到正确的返回结果
1234567
function getDataByAjax () {return $.ajax(...postParam)}var data = getDataByAjax()if (data) { console.log(data.info)}
"哦,你这里是异步调用,不能直接获得返回值,你要把if语句写到回调函数中",小飞不假思索的说到,对于一个‘专业’的fe来说,这根本不是一个问题。“可是我希望只是改造getDataByAjax这个方法,让后面的代码成立。”“研究这个没有意义,异步是js的精髓,同步的话会阻塞js调用,超级慢的,但是你要一再坚持的话,用async:true就好了”“不愧是大神,我回去立刻试一试,么么哒”
两天后,她哭丧着脸登上了qq“试了一下你的方法,但是根本行不通,哭~~”“别急,我看看你这个postParam的参数行吗”
123456
{... dataType: 'jsonp',async: true...}
"这是一个jsonp请求啊,老掉牙的东西了,,jsonp请求是没有办法同步的"“我知道jsonp请求的原理是通过script标签实现的,但是,你看,script也是支持同步的呀,你看tags/attscriptasync.asp”“额,那可能是jquery没有实现吧,哈哈”“大神,你能帮我实现一个jsonp的同步调用方式嘛,拜托了(星星眼)”虽然他有点奇怪jquery为什么没有实现,但是既然w3school的标准摆在那里,码两行代码又没什么,
1234567891011121314
export const loadJsonpSync = (url) => {var result; window.callback1 = (data) => (result = data)let head = window.document.getElementsByTagName('head')[0]let js = window.document.createElement('script') js.setAttribute('type', 'text/javascript') js.setAttribute('async', 'sync') // 这句显式声明强调src不是按照异步方式调用的 js.setAttribute('src', url) head.appendChild(js)return result}
额,运行起来结果竟然是undefined!w3cshool的文档竟然也不准,还权威呢,我看也不怎么着,小飞暗自想到。
“刚才试了一下,w3school文档上写的有问题,这个异步属性根本就是错的”“可是我刚还试过一次这个,我确认是好的呀”
12

(有兴趣的同学可以实现以下两个js,并且加上async的标签进行尝试。)“这个,我就搞不清楚了”,小飞讪讪的说到对方已离线
抽象
关于这个问题,相信不只是小飞,很多人都难以解答。为什么ajax可以做到同步,但jsonp不行,推广到nodejs上,为什么readFile也可以做到同步(readFileSync),但有的库却不行。(至于script的async选项我们暂时避而不谈,是因为现在的知识维度暂时还不够,但是不要着急,下文中会给出明确的解释)现在,让我们以计算机科学的角度抽象这个问题:
我们是否可以将异步代码转化为同步代码呢?(ASYNCCALL => SYNCCALL)
既然是抽象问题,那么我们就可以不从工程角度/性能角度/实现语言等等等方面来看(同步比异步效率低下),每增加一个维度,复杂程度将以几何爆炸般增长下去。
首先,我们来明确一点,==在计算机科学领域==同步和异步的定义
同步(英语:Synchronization),指对在一个系统中所发生的事件(event)之间进行协调,在时间上出现一致性与统一化的现象。在系统中进行同步,也被称为及时(in time)、同步化的(synchronous、in sync)。--摘自百度百科异步的概念和同步相对。即时间不一致,不统一
明确了这一点,我们可以借助甘特图来表示同步和异步
其中t1和t2是同步的,t1和t3是异步的。答案就在操作系统原理的大学教材上,我们有自旋锁,信号量来解决问题,伪代码如下
1234567891011121314151617
spinLock () {// 自旋锁 fork Wait 3000 unlock() //开启一个异步线程,等待三秒后执行解锁动作 loop until unlock // 不断进行空循环直到解锁动作Put ‘unlock’} //pv原语,当信号量为假时立即执行下一步,同时将信号量置真//反之将当前执行栈挂起,置入等待唤醒队列//uv原语,将信号量置为假,并从等待唤醒队列中唤醒一个执行栈Semaphore () { pv() fork Wait 3000 uv() pv() uv()Put 'unlock'}
很好,至此都可以在操作系统原理的教材上翻到答案。于是我们在此基础上添加约束条件
仅仅依赖于js本身,我们是否可以将异步代码转化为同步代码呢?(ASYNCCALL => SYNCCALL)
论证
带着这个问题,我们翻看一下jquery的源码src/ajax/xhr.js#L42可以看出, ajax的同步机制本质上是由XMLHttpRequest实现的,而非js原生实现。同样的道理,我们再翻看一下nodejs的源码lib/fs.js#L550从readFileSync->tryReadSync->readSync一路追下去,会追到一个c++ binding, node_file.cc#L1167
123456
if (req->IsObject()) { ASYNC_CALL(read, req, UTF8, fd, &uvbuf, 1, pos);} else { SYNC_CALL(read, 0, fd, &uvbuf, 1, pos) args.GetReturnValue().Set(SYNC_RESULT);}
同步的奥妙在于c++的宏定义上,这是一种借由c++来实现的底层同步方式。观察了这两种最广泛的异步转同步式调用,我们发现均没有采用js来实现。似乎从现象层面上来看js无法原生支持,但是这还不够,我们探究在js语义下上面的自旋锁/信号量的特性模拟实现(我知道你们一定会嗤之以鼻,==js本身就是单线程的,只是模拟了多线程的特性== 我无比赞同这句话,所以这里用的不是实现,而是特性模拟实现),另外,由于settimeout具有fork相似的异步执行特性,所以我们用setitmeout暂时代替fork
自旋锁
1.第一个实现版本
1234567
var lock = truesetTimeout(function () {lock = false}, 5000) while(lock);console.log('unlock')
我们预期在5000ms后执行unlock语句,但是悲剧的是,整个chrome进程僵死掉了。为了解释清楚这个问题,我们读一下阮一峰老师的event loop模型event-loop.html看样子咱们已经清楚的了解了event loop这个js运行顺序的本质(同步执行代码立即执行,异步代码入等待队列),那么,我们可以基于此给出js vm的调度实现(eventloop的一种实现),当然,咱们为了解释自旋锁失败只需要模拟异步操作, 同步操作,和循环就好
123456789101112138008138004
//taskQueue:任务队列//runPart:当前正在执行的任务(同步指令集)//instruct: 正在执行的指令 function eventloop (taskQueue) {while(runPart = taskQueue.shift()) {while(instruct = runPart.shift()) {const { type, act, codePart } = instructswitch(type) {case 'SYNC': console.log(act)if (act === 'loop') runPart.unshift({ act: 'loop', type: 'SYNC'})breakcase 'ASYNC': taskQueue.push(codePart)break}}}}
然后转化我们的第一个版本自旋锁
1234567891011121380081920
let taskQueue = [[{act: 'var lock = true', type: 'SYNC'}, //var lock = true{ act: 'setTimeout', type: 'ASYNC', codePart: [{act: 'lock = false', type: 'SYNC'}]}, // setTimeout(function () { lock = false }, 5000)/*{ act: 'loop', type: 'SYNC' },*/ // while(lock);{ act: 'console.log(\'sync\')', type: 'SYNC'} // console.log('unlock')]]
测试一下,符合evnet loop的定义,然后放开注释,我们成功的让loop block住了整个执行过程,lock = false永远也没有机会执行!!!(真实的调度机制远比这个复杂的多得多的,有兴趣的可以看看webkit~~~的jscore的实现哈)
知道了原理,我们就来手动的改进这部分代码2.改进的代码
12345678910111213141516
var lock = truesetTimeout(function () {lock = false console.log('unlock')}, 5000) function sleep() {var i = 5000while(i--);} var foo = () => setTimeout(function () { sleep()lock && foo()})foo()
这个版本的改进我们对while(true);做了切块的动作,实际上这种技巧被广泛的应用到改善页面体验的方面,所以,有些人因为时序无法预知而抗拒使用settimeout这种想法是错误的!6996528,
小测验1: 改写eventloop和taskQueue,使它支持改进后的代码
可是,如果把代码最后的foo() 变成 foo() && console.log('wait5sdo'),我们的代码依然没有成功,why
注意看我们标红的地方,如果你完成了小测验1,就会得到和这张图一致的顺序
==同步执行的代码片段必然在异步之前。==
所以,无论从理论还是实际出发,我们都不得不承认,在js中,把异步方法改成同步方法这个命题是水月镜花
哦对了,最后还需要解释一下最开始我们埋下的坑, 为什么jsonp中的async没有生效,现在解释起来真的是相当轻松,即document.appendChild的动作是交由dom渲染线程完成的,所谓的async阻塞的是dom的解析,而非js引擎的阻塞。实际上,在async获取资源后,与js引擎的交互依旧是push taskQueue的动作,也就是我们所说的async call
推荐阅读: 关于dom解析请大家参考webkit技术内幕第九章资源加载部分
峰回路转
相信很多新潮的同学已经开始运用切了async/await语法,在下面的语法中,getAjax1和console之间的具有同步的特性
1234
async function () {var data = await getAjax1() console.log(data)}
讲完了event loop和异步的本质,我们来重新审视一下async/await。老天,这段代码亲手推翻了==同步执行的代码片段必然在异步之前。== 的黄金定律!惊不惊喜,意不意外,这在我们的模型里如同三体里的质子一样的存在。我们重新审视了一遍上面的模型,实在找不到漏洞,找不到任何可以推翻的点,所以真的必须承认,async/await绝对是一个超级神奇的魔法。到这里来看我们不得不暂时放弃前面的推论,从async/await本身来看这个问题相信很多人都会说,async/await是CO的语法糖,CO又是generator/promise的语法糖,好的,那我们不妨去掉这层语法糖,来看看这种代码的本质, 关于CO,读的人太多了,我实在不好老生常谈,可以看看这篇文章,咱们就直接绕过去了,这里给出一个简易的实现/5800210.html
1234567891011121380081920
function wrap(wait) {var iter iter = wait()const f = () => {const { value } = iter.next() value && value.then(f)} f()} function *wait() {var p = () => new Promise(resolve => { setTimeout(() => resolve(), 3000)})yield p() console.log('unlock1')yield p() console.log('unlock2') console.log('it\'s sync!!')}
终于,我们发现了问题的关键,如果单纯的看wait生成器(注意,不是普通的函数),是不是觉得非常眼熟。这就是我们最开始提出的spinlock伪代码!!!这个已经被我们完完全全的否定过了,js不可能存在自旋锁,事出反常必有妖,是的,yield和*就是表演async/await魔法的妖精。generator和yield字面上含义。Gennerator叫做生成器,yield这块ruby,python,js等各种语言界争议很大,但是大多数人对于‘让权’这个概念是认同的(以前看到过maillist上面的争论,但是具体的内容已经找不到了)
扩展阅读---ruby元编程 闭包章节yield(ruby语义下的yield)
所谓让权,是指cpu在执行时让出使用权利,操作系统的角度来看就是‘挂起’原语,在eventloop的语义下,似乎是暂存起当时正在执行的代码块(在我们的eventloop里面对应runPart),然后顺序的执行下一个程序块。我们可以修改eventloop来实现让权机制
小测验2 修改eventloop使之支持yield原语
至此,通过修改eventloop模型固然可以解决问题,但是,这并不能被称之为魔法。
和谐共存的世界
实际上通过babel,我们可以轻松的降级使用yield,(在es5的世界使用让权的概念!!)看似不可能的事情,现在,让我们捡起曾经论证过的==同步执行的代码片段必然在异步之前。== 这个定理,在此基础上进行进行逆否转化
==在异步代码执行之后的代码必然不是同步执行的(异步的)。==
这是一个圈子里人尽皆知的话,但直到现在他才变得有说服力(我们绕了一个好长的圈子)现在,让我们允许使用callback,不使用generator/yield的情况下完成一个wait generator相同的功能!!!
1234567891011121380081920
function wait() {const p = () => ({value: new Promise(resolve => setTimeout(() => resolve(), 3000))})let state = {next: () => { state.next = programPartreturn p()}}function programPart() { console.log('unlocked1') state.next = programPart2return p()}function programPart2() { console.log('unlocked2') console.log('it\'s sync!!')return {value: void 0}}return state}
太棒了,我们成功的完成了generator到function的转化(虽然成本高昂),同时,这段代码本身也解释清楚了generator的本质,高阶函数,片段生成器,或者直接叫做函数生成器!这和scip上的翻译完全一致,同时拥有自己的状态(有限状态机)
推荐阅读 计算机程序的构造和解释 第一章generator部分小测验3 实际上我们提供的解决方式存在缺陷,请从作用域角度谈谈
其实,在不知不觉中,我们已经重新发明了计算机科学中大名鼎鼎的CPS变换Continuation-passing_style
最后的最后,容我向大家介绍一下facebook的CPS自动变换工具--regenerator。他在我们的基础上修正了作用域的缺陷,让generator在es5的世界里自然优雅。我们向facebook脱帽致敬!!egenerator
后记
同步异步 可以说是整个圈子里面最喜欢谈论的问题,但是,谈来谈去,似乎绝大多数变成了所谓的‘约定俗称’,大家意味追求新技术的同时,却并不关心新技术是如何在老技术上传承发展的,知其然而不知其所以然,人云亦云的写着似是而非的js。
==技术,不应该浮躁==
PS: 最大的功劳不是CO,也不是babel。regenerator的出现比babel早几个月,而且最初的实现是基于esprima/recast的,关于resprima/recast,国内似乎了解的并不多,其实在babel刚刚诞生之际, esprima/esprima-fb/acron 以及recast/jstransfrom/babel-generator几大族系围绕着react产生过一场激烈的斗争,或许将来的某一天,我会再从实现细节上谈一谈为什么babel笑到了最后~~~~

阅读更多 >>>  java中文乱码,用java读取txt档案中的中文写入资料库出现中文乱码,怎么解决?

来自一位react新手的react入门须知

所有的html,css都可以写在js中,这就是jsx的用法。
用于验证数据的类型是否是满足你的需要,不过我在现有的项目中没有特意的指定数据的propTyoe,因为这些都是前后端约定好的。
此用法如下图 :
这个如同vue组件里面的props中的type:Array这个一样
这个与vue-router差不多,大家可以看文档。
react-router的中文官网 : 中文官网
因为react与vue一样,都是使用vitural-dom,没有处理dom节点,从而大大提高了页面的渲染效率。
当你想要获取真实的dom节点的时候,可以使用ref,具体的使用,可以看阮一峰的react入门,我下面的todolist的demo里面也会涉及到。
不过在你使用无状态组件申明组件的时候,ref在这个组件中是不能使用的。
可以通过webpack安装各种依赖,我使用的最爽的一个就是react-hot-loader,就是热更新,非常好用。不过热更新其他的工具,比如 browser-sync ,下面是一些文档。
如vue的vue-cli脚手架, create-react-app ]( https://github.com/facebookincubator/create-react-app ),使用以上方法的话,与vue-cli脚手架工具类似
我自己的一些总结,单单学react是不难的,难的是要和一些工具混合来用,往往这个过程的成本最高。比如使用webpack构建,redux管理状态, redux-thunk 或者 redux-saga 来处理异步action。
还有一个很大的趋势就是前端变化很快,拿 react-router 来说,你做了一个项目, react-router@2.0.0 是能完美跑起来的,但是换成了当换成了 react-router@3.0.0 ,基本上就跑不起来了,更何况现在的 react-router 已经出到4.0,
相应的 webpack 也是这样,当时一些开发者基于 webpack1.0 开发的,当webpack升到2.0的时候, webpack.config,js 里面的文件要重新配置了。现在 webpack 已经更新到了3.0。
2, 阮一峰的文档: react的入门 ,webpack的入门, react-router
3,react的一些框架和一些轮子:
4,一个渐进的学react的demo。
里面基本上涉及到了,react入门的所有涵盖的知识,他都是自己搭的,没有使用脚手架工具。里面也涵盖了webpack的一些配置,对于新手学习蛮好的。
?
1,jquery、vue、react的todolist,最简单的
2,基于ant-dedign的一个react简单的demo
3,基于react写的一个简易大众点评的demo,里面用到了redux,mock,fetch,es6

阮一峰的介绍

阮一峰,70后,英文名Frank。他原是上海财经大学世界经济博士研究生。主要研究宏观金融、货币政策与美国经济。于2008年6月获得博士学位。目前在上海一所当地大学(上海金融学院 国际经贸学院)任教。他本人也是一名IT技术人员,主要关注网站制作,并且对免费软件有着坚定不移的信念。除了写博客以外,他还有三个网站:微趣、Italo Calvino in China和读书公园。

网站数据信息

"阮一峰js教程,来自一位react新手的react入门须知"浏览人数已经达到16次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:阮一峰js教程,来自一位react新手的react入门须知的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!